熟悉 Nginx 的小伙伴都知道, Nginx 是一个非常好的负载均衡器除了用的非常普遍的 Http 负载均衡, Nginx 还可以实现 Email,FastCGI 的负载均衡, 甚至可以支持基于 Tcp/UDP 协议的各种应用的负载均衡 (比如 MySQL,DNS 等) 这些功能分别在 Nginx 的不同模块实现了负载均衡可以看成 Nginx 对外提供的一种服务
我们先来简单介绍下 Nginx 负载均衡的基本的功能并且, 我们在下面的介绍中会同时罗列 Nginx Plus(Nginx 的扩展板, 部分功能收费)
介绍
在多个应用程序实例之间做负载平衡是一种常用的优化资源利用最大化吞吐量减少延迟和确保容错配置的技术而使用 Nginx 可以作为一个高效的 Http 负载均衡器将流量分摊到各个服务器上, 从而改善性能, 增加扩展性和可靠性
简单配置
负载均衡的基本配置十分的简单, 在基本配置上, 你可以添加更多的指令来满足自己个性化的需求
如下:
- http {
- upstream myapp1 {
- server srv1.example.com;
- server srv2.example.com;
- server srv3.example.com;
- }
- server {
- listen 80;
- location / {
- proxy_pass http://myapp1;
- }
- }
- }
上面, 所有的请求都将被代理到服务器组 myapp1 上, myapp1 上有三台服务器 srv1-srv3, 这三台服务器将要分摊请求如果没有指定负载均衡方法, 那么默认的方法是 round-robin
在 nginx 中, HTTP,HTTPS,FastCGI,uwsgi,SCGI 都可以做反向代理, 并且可以做负载均衡, 上面的例子是 http 的要使用 https 的负载均衡, 简单的将 http 改为 https 即可
负载均衡的常用算法
负载均衡的方法,
就是 Http 请求如何被分配到各个服务器上的算法常用的负载均衡的常用算法有以下种:
RoundRobin 默认的方法, 也是最简单的一种即 Http 请求按照服务器列表罗列的顺序一次进行分配;
Least Connections 在这种方式下, 每个请求被发送到当下具有最小有效连接数的服务器上, 当然权重也会被考虑进去比如当下有三台服务器 A/B/C, 当下各自的连接数是 100/200/300, 那么下一个请求过来就会被分配到 A 服务器进行处理
Hash 用户定义一个 Hash 的 Key 值, 比如 IP 或者 URL, 将这个 Hash 的 Key 和服务器做一次映射, 每次请求过来都会按照这个映射被分配到同一台服务器
IP Hash (仅适用于 Http 负载均衡的情况), 根据客户端 IP 的前三个字节 (比如 IP 是 10.25.2.10 那么就拿 10.25.2 做映射) 来分配请求, 这个和上一种类似
Least Time 即最少时间新的请求将被发往拥有最快响应时间和最少连接数的上游服务器这是 Nginx Plus 才具有的方式
最少连接算法
即 Least Connections 这种算法最少连接, 顾名思义, 就是当下谁的连接数最少请求就然该谁来处理这是一种相对公平的方式, 防止某些服务器负载过重, 将请求分配到相对清闲的服务器上去基本的配置如下:
- upstream myapp1 {
- least_conn;
- server srv1.example.com;
- server srv2.example.com;
- server srv3.example.com;
- }
需要指定 least_conn 指令
Session 一致性问题
如果负载均衡采用 round-robin 或者 least-connected 算法, 同一个客户端发送过来的不同请求就有可能被不同的 server 处理, 这种情形下就不能保证两次请求 session 的一致性
为了解决这个问题, 可以采用第三种负载均衡的算法, 那就是 ip-hash 有了 IP 哈希, 将客户端的 IP 和服务器组列表的几个服务器之间建立一种对应关系, 那么每个客户端的每次请求就只能被分配到一台 server 上面, 从而保证 session 的一致性 ip-hash 的方式配置如下:
- upstream myapp1 {
- ip_hash;
- server srv1.example.com;
- server srv2.example.com;
- server srv3.example.com;
- }
负载均衡权重
说是负载 "均衡", 但是不是说每个 server 的分配的请求是完全一样前面讨论的各个服务器组, 里面的各个 server 其实是地位平等利益均沾事实上, 由于每个 server 的特性可能不一样, 有些 server 硬件条件好, 稳定性高, 理应多处理些请求, 相反另一些不太稳定的 server 就应该适当的少分配请求我们可以为这些 server 分配不同的权重, 来定义它们在处理请求时所扮演角色的重要性权重用指令 weight 来表示, 权重高表示选择的几率更大, 权重低表示选中的几率更小, 权重为 0 表示始终不选用以 round-robin 算法为例:
- upstream myapp1 {
- server srv1.example.com weight=3;
- server srv2.example.com;
- server srv3.example.com;
- }
没有 weight 指令的默认其为 1 如果有 5 个请求过来, 理想情况下 srv1 就能接到 3 个, srv2 和 srv3 各一个
服务器健康检查
反向代理的各种实现 (如 http/https/FastCGI) 还可以对各个 server 做健康检查如果请求一个 server 错误(如返回 500, 究竟如何才为失效, 在 Nginx Plus 中做了扩展),nginx 就将这个 server 标记为失效的, 在接下来一段时间的请求中就会避免选择这台 server 究竟这端时间要多长才合适? 有 max_fails 和 fail_timeout 参数来定义
max_fails
默认是 1, 表示在 fail_timeout 时间内, 有多少次对某个 server 的访问失败, 就算作这台 server 的正式失效(你总要给人家多表现几次的机会撒), 默认情况下就是 1 次;
fail_timeout
默认是 10s, 有两层含义, 一就是为 max_fails 指令限定一个时间范围, 二就是如果 server 已经被标记为失效, 那么过了这个时间后, 你就应该分配个请求去试探下这个 server, 是否已经可用了 (你总的给人家重新做人的机会) 如果还是不可用, 那么此 server 继续被标记为失效的 server, 如果已经可用了那么就重新标记为活跃, 在接下来的请求中, 继续按照 round-robin/ip-hash 等算法和权重给它分配请求, 和平常无异
除了这些指令之外 proxy_next_upstream, backup, down, 和 keepalive 也针对负载均衡功能做了不同的限定
以上这些功能是基本是 Nginx 的免费版本提供的, 其实负载均衡里可以说的话题还多着呢我们下篇文章中谈谈 Nginx Plus 提供的更为丰富的负载均衡的功能
来源: https://www.cnblogs.com/minirice/p/8553778.html