Nginx: 负载均衡基础配置, 加权轮序, hash算法, ip_hash算法, least_conn算法

2024-08-29 01:36

本文主要是介绍Nginx: 负载均衡基础配置, 加权轮序, hash算法, ip_hash算法, least_conn算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

负载均衡

  • 在真正的反向代理场景中,必然涉及到的一个概念,就是负载均衡
  • 所谓负载均衡,也就是将Nginx的请求发送给后端的多台应用程序服务器
  • 通常的应用程序服务器,后面的每台服务器都是一个同等的角色,提供相同的功能
  • 用户发送一个request 到我们的这个负载均衡器(Nginx)
  • 负载均衡器会将这个请求发给后端的任何一台服务器
  • 它会依据一定的负载均衡算法去后端的三台服务器中选择其中的一台
  • 从而将这个请求发送给后端这个应用程序服务器
  • 由应用程序服务器处理完之后,再次的返回给负载均衡器
  • 由负载均衡器再把这个响应的结果给传递给我们的用户
  • 在整个这样一个过程中,对于负载均衡器和后端的应用程序服务器来说
  • 它这三台服务器提供的角色通常来说是一样的
  • 比如说在某些场景下,后端的这个应用服务器可能都是一台mysql数据库服务器
  • 在mysql数据库服务器中,通常我们用的最多的一种性能是读请求读,请求压力会很大
  • 在一组两重的架构中,第一台服务器可能是用来写的,第二台和第三台都是用来读的
  • 当然很多情景下,我们第一台服务器也可以用来读
  • 这个时候所有的读请求,就都可以平均的分发到我们后端这些服务器

1 )场景举例1

  • 现在,后端的一个应用程序服务器提供了一个电商站点,
  • 这个时候我的用户可能需要去登录到自己的账户中,然后去买商品
  • 用户会首先发起个请求到负载均行器,负载均行器再发到应用服务器
  • 这个时候我们用户登录账户之后,账号信息保存在应用服务器一上
  • 这个时候我们的用户就去浏览我们的网页,选商品,之后,加到购物车
  • 这个时候,假如他一刷新页面,这会触发一个新的HTTP请求
  • 这个请求也会到负载均容器,但被分配到第二台服务器上了,这样用户信息丢失了
  • 后续操作可能会要重新登录,这种场景对用户来说是不能接受的
  • 对于这样一种情形来说,涉及到后端的三台应用服务器如何去对session进行共享?
  • 这是负载均衡器需要面临的第一个问题

2 )场景举例2

  • 负载均衡器在分发请求的时候,三台服务器,如果所有的角色能力都一样,服务器硬件规格也一样
  • 可能是第一次发给第一,第二次发给第二,第三次发给第三,第四次再发给第一,这样轮询
  • 假如,服务器有些性能处理能力很强,有些性能处理很弱,如何合理的分发这样一些请求 ?
  • 也就是说负载均衡器在选择后端的应用服务的时候,要依据一定的算法, 算法设定的优劣
  • 对于负载均衡的效果起到了决定性的影响的,其实没有一个绝对的优劣之分
  • 所有的这些负载均衡的算法,都各自有一些不同的适用场景,需要去结合业务来进行选择使用

3 )场景举例3

  • 在反向代理的场景下,这些应用服务器上面,某些缓存信息是如何结合Nginx进行保存的?

Nginx 对上游服务负载均衡

1 )回顾 upstream 段

  • 语法:upstream name { … }

  • 默认值:无

  • 上下文:http

  • 示例

    upstream {............
    }
    
  • 指令:

    • server address [parameters];
      • weight=number
      • max_conns=nuimber
      • fail_timeout=time
      • max_fails=number
      • backup
      • down
    • keepalive connections;
    • keepalive_request number;
    • keepalive_timeout time;
    • queue;
  • 配置示例

upstream back_end {server 127.0.0.1:8080 weight=3 max_conns=1000 fail_timeout=10s max_fails = 2;keepalive 32;keepalive_requests 50;keepalive_timeout 30s;
}

2 ) 实际部署

2.1 应用服务器 (使用 nginx 模拟),比如当前ip地址为:192.168.184.20

server {listen 8020;location / {return 200 'Return Result For Server 8020\n';}
}server {listen 8021;location / {return 200  'Return Result For Server 8021\n';}
}server {listen 8022;location / {return 200 'Return Result For Server 8022\n';}
}

这里 模拟3台 应用服务器

2.2 nginx 服务器

upstream demo_server {server 192.168.184.20:8020 weight=3 max_conns=50 fail_timeout=10s max_fails=2;server 192.168.184.20:8021 weight=2;server 192.168.184.20:8022 weight=1;
}server {listen 			80;server_name 	balance.baidu.com;location /balance/ {proxy_pass		http://demo_server;}
}

哈希算法

  • 上面的示例,演示的是加权轮询的方式,在分配请求的时候,会保持这个分配比例,而非严格按照顺序分配
  • 现在,来看新的一个负载均衡算法 — 哈希算法
  • 定义:哈希算法是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值我们称之为哈希值,散落明文到哈希值的映射是不可逆的
  • 简单来说,哈希算法就是根据一个固定内容的值,经过哈希运算之后,可以得到一个唯一的值
  • 哈希算法有很多种,但是它的思想都是一样的,总的来说,它是根据一个内容经过一定的哈希值换算之后得到一个固定长度的一个字符串
  • 对一个文件内容不变的文件来说,它永远会得到一个相同的字符串值,这个算法可以解决文件传输前后校验是否一致的场景
  • 比如说,现在有两个文件,左侧的上和下,是不一样的,别看多了一行,就是多了一个字节,计算出来的内容都不会一样

1 )哈希指令

  • 语法:hash key [consistent];
    • 这个key 通常是一个内容, 可以使用变量,特定内容的变量
    • 可以根据请求头的内容来进行哈希运算,
    • 如果头部的某些内容来源一样,哈希值一定一致
    • 或者根据客户端的ip
  • 默认值:无
  • 上下文:upstream

2 )配置示例

2.1 这里使用Nginx模拟应用服务器

server {listen 	10020;location / {return 200 'Return Result For Server 10020\n';}
}server {listen 	10010;location / {return 200 'Return Result For Server 10010\n';}
}

2.2 应用服务器

upstream demo_server_1 {hash 		$request_uri;server  	192.168.184.20:10020;server  	192.168.184.20:10010;
}server {listen 		80;server_name balance_hash.baidu.com;location / {proxy_pass http://demo_server_1;}
}
  • 在上述两台服务器中,假如,请求在一台服务器上有缓存,在另一台是用不了的
  • 某一些情形下,为了保证来自同一个客户端的请求,总是能够分配到指定的一台服务器上
  • 可能需要根据这样一个哈希算法,把其永远分配到某一个服务器上,而不会再调度到另外一台服务器上
  • 其实最初它的一个设计应用是在缓存中用的比较多,像CDN这样的场景

IP Hash 算法

  • 哈希算法是可以指定各种不同的key来进行一个哈希运算,这适用于我们一些比较复杂的一个应用场景
  • 我们有一些特殊需求,比如,根据某一些应用层的信息,HTTP请求投入的某一些具体信息
  • 或者是请求行中的某一些具体信息来进行一个哈希运算
  • 它就是根据IP进行哈希运算,因为从这个算法的名称上也能够看出来

1 ) ip_hash 指令

  • 语法:ip_hash

  • 默认值:无

  • 上下文:upstream

  • 示例配置

    upstream demo_server_1 {ip_hash    # 只加这一个配置就行server  	192.168.184.20:10020;server  	192.168.184.20:10010;
    }
    
  • 其实, ip_hash 指令是为了解决Nginx和后端应用程序服务器的一个 session 保持的

  • 它其实对出的一个应用场景,也是对于这种 session 保持的解决而生的

  • 某一些客户端在请求完服务器之后,常会有cookie信息一些

  • 对应到服务器端的时候,会有 session 信息, 对于不同的用户来说是不同的

  • 对于固定的客户端来说,使用ip hash这样一种负载运用算法来进行 session 保持

  • 无疑是一个简错的选择

最少连接数算法

  • 不管是 hash 还是 ip_hash,还是加权轮循的负载均衡算法,其实都忽略了一个重要的事实
  • 对于这些算法来说,没有将后端应用服务器当前的一个负荷状况给考虑在内
  • 只是根据我们从用户发来的请求做一些负带均衡算法的挑选或者是加权轮型就更简单粗暴了
  • 不会把任何因素考虑在内,而只是简单的将请求逐个分发
  • 包括 hash 或者 ip_hash,他们只能根据某一些特定的属性来对后端进行分发的
  • 但是这些属性也仅仅是来自于用户的请求,其实这样一些场景是不合理的
  • 比如说,现在应用服务器一的处理能力很强,应用服务器二和三处理能力特别的弱
  • 你看之前的这些算法就不合理了
  • 都没有将后端服务器的一个当前运行状态就是作为服务器分发请求的一个策略
  • 现在引入最少连接算法,它考虑上游服务器的一个情况所决定的一种算法

1 )最少连接算法

  • 从上游服务器,挑选一台当前已建立连接数最少的分配请求
    • Nginx 在收到用户请求之后,在如何去挑选后端应用服务器的时候
    • 会去考虑当前这个应用服务器具体已经建立了多少个连接,已经正在处理多少用户请求
    • 他会找最少的,将请求分发给这个
    • 在某些情形下,总是挑选当前后端应用服务器正在处理连接数最少的那台进行分发请求
  • 极端情形下退化为 rr 算法
    • 当服务器分配数都一样的场景下
    • 会退化到轮循算法,逐个分发

1.1 least_conn 指令

  • 模块 ngx_http_upstream_least_conn_module
  • 禁用通过 --without-http_upstream_least_conn_module
  • 语法:least conn;
  • 默认值:无
  • 上下文:upstream
  • 基于此算法的Nginx在挑选应用程序服务器的时候会找当前处理请求数最少的一个
  • 存在多个 worker 子进程的时候,Nginx 是一个 worker 子进程的情形下,就有一个work子进程
  • 每一次的请求它都会分配到不同的worker子进程中,不同的worker子进程,是怎么样知道每一个应用服务器,当前正在处理的请求有多少,包括它当前的一个响应状态是怎么样的
  • 也就是说,我们的后端应用服务器的一个具体状态信息,是没办法在不同的worker子进程之间共享的
  • 解决办法:在Nginx上去开辟出一块内存空间
    • worker 子进程在处理这个用户请求的时候,都会将后端对应的应用程序服务器的一个当前状态
    • 比如说它当前正在处理的一个用户连接数,访问失败的次数等服务器的一个共态信息给保存到共享内存中
    • 这样实现了最少连接的算法

1.2 zone 指令

  • 用于指定共享内存空间大小
  • 语法:zone name [size];
  • 默认值:无
  • 上下文:upstream
  • 示例
    upstream demo_server_1 {zone        test     10M;least_conn;server  	192.168.184.20:10020;server  	192.168.184.20:10010;
    }
    
  • 在某一些场景中会有用的,但是它用的也并不是很多

这篇关于Nginx: 负载均衡基础配置, 加权轮序, hash算法, ip_hash算法, least_conn算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116466

相关文章

关于Maven中pom.xml文件配置详解

《关于Maven中pom.xml文件配置详解》pom.xml是Maven项目的核心配置文件,它描述了项目的结构、依赖关系、构建配置等信息,通过合理配置pom.xml,可以提高项目的可维护性和构建效率... 目录1. POM文件的基本结构1.1 项目基本信息2. 项目属性2.1 引用属性3. 项目依赖4. 构

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

mysql-8.0.30压缩包版安装和配置MySQL环境过程

《mysql-8.0.30压缩包版安装和配置MySQL环境过程》该文章介绍了如何在Windows系统中下载、安装和配置MySQL数据库,包括下载地址、解压文件、创建和配置my.ini文件、设置环境变量... 目录压缩包安装配置下载配置环境变量下载和初始化总结压缩包安装配置下载下载地址:https://d

shell脚本快速检查192.168.1网段ip是否在用的方法

《shell脚本快速检查192.168.1网段ip是否在用的方法》该Shell脚本通过并发ping命令检查192.168.1网段中哪些IP地址正在使用,脚本定义了网络段、超时时间和并行扫描数量,并使用... 目录脚本:检查 192.168.1 网段 IP 是否在用脚本说明使用方法示例输出优化建议总结检查 1

gradle安装和环境配置全过程

《gradle安装和环境配置全过程》本文介绍了如何安装和配置Gradle环境,包括下载Gradle、配置环境变量、测试Gradle以及在IntelliJIDEA中配置Gradle... 目录gradle安装和环境配置1 下载GRADLE2 环境变量配置3 测试gradle4 设置gradle初始化文件5 i

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法