什么是Nginx upstream?
Nginx 模块一般分为三大类:handler、filter和upstream。
利用 handler、filter 这两个模块,可以使 Nginx 轻松完成任何单机工作。
upstream 模块将使 Nginx 跨越单机的限制,完成网络数据的接收、处理和转发 。
数据转发功能为 Nginx 提供了跨越单机的横向处理能力,使得 Nginx 摆脱了只能为终端节点提供单一功能的限制,而使它具备了网络应用级别的拆分、封装和整合的战略功能。
ngx_http_upstream_module 模块
ngx_http_upstream_module模块 用来定义 proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass 和 grpc_pass 指令引用的一组服务器。这组服务器可以用来做负载均衡,提高服务器的高可用性
我们在配置时主要配置服务器组和调度算法
负载均衡算法
# http contextupstream backend_hosts {server host1.example.com;server host2.example.com;server host3.example.com;
}server {listen 80;server_name example.com;location /proxy-me {proxy_pass http://backend_hosts;}
}
以上,我们配置了一组名为backend_hosts的服务器组。这组服务器组名被定义后,名称将被当做常规域名在 proxy_pass 中使用。
在例子中,example.com/proxy-me 发起的请求都会被转发到上面定义的服务器组中。默认情况下,每个请求会一次从上到下路由到不同的主机。
选择合适的负载均衡算法
upstream 模块提供了四种算法可供选择:
- round robin:默认的负载均衡算法。如果服务器组未定义负载均衡算法,将会用轮询的方式将请求路由到服务器组中的主机。
- least_conn:该算法会把新请求路由到具有最少活动连接的后端主机中,同时考虑服务器的权重。如果有多个这样的服务器,则会尝试使用加权轮询平衡算法。
- ip_hash:根据客户端IP在服务器组中分配请求。该算法保证来自统一客户端的请求将始终传递到同一服务器,除非该服务器不可用。
- hash:为 client-server 映射一个基于散列值的服务器组,可以包含文本、变量或者他们的组合。如果从服务器组中新增或删除服务器,可能会导致大量 key 重新映射
例:
upstream backend {ip_hash;server backend1.example.com;server backend2.example.com;server backend3.example.com **down**;server backend4.example.com;
}
常用参数
- weight=number 设置服务器的权重,默认为1
- max_conns=number 限制到代理服务器的同时活动连接的最大值。默认为0,无限制。如果服务器组不驻留在共享内存中,则该限制适用于每个工作进程。
- max_fails=number 表示失败几次,则标记server已宕机,剔除上游服务。
- fail_timeout=time 表示失败的重试时间。默认值是 10 秒
- backup 表示备用服务器
健康检查
Nginx 默认判断失败节点状态以 connect refuse 和 time out 状态为准,不以 HTTP 错误状态进行判断失败 。因为HTTP只要能返回状态说明该节点还可以正常连接,所以nginx判断其还是存活状态;
除非添加了proxy_next_upstream指令设置对404、502、503、504、500和time out等错误进行转到备机处理,在next_upstream过程中,会对fails进行累加,如果备用机处理还是错误则直接返回错误信息(但404不进行记录到错误数,如果不配置错误状态也不对其进行错误状态记录)
综述,nginx记录错误数量只记录timeout 、connect refuse、502、500、503、504这6种状态,timeout和connect refuse是永远被记录错误状态。
而502、500、503、504只有在配置proxy_next_upstream后nginx才会记录这4种HTTP错误到fails中,当fails大于等于max_fails时,则该节点失效
nginx 处理节点失效和恢复的触发条件
- 失效:nginx可以通过设置max_fails(最大尝试失败次数)和fail_timeout(失效时间,在到达最大尝试失败次数后,在fail_timeout的时间范围内节点被置为失效,除非所有节点都失效,否则该时间内,节点不进行恢复)对节点失败的尝试次数和失效时间进行设置,
- 恢复:当超过最大尝试次数或失效时间未超过配置失效时间,则nginx会对节点状会置为失效状态,nginx不对该后端进行连接,直到超过失效时间或者所有节点都失效后,该节点重新置为有效,重新探测;
所有节点失效后nginx将重新恢复所有节点进行探测:
如果探测所有节点均失效,备机也为失效时,那么nginx会对所有节点恢复为有效,重新尝试探测有效节点,如果探测到有效节点则返回正确节点内容,如果还是全部错误,那么继续探测下去,
当没有正确信息时,节点失效时默认返回状态为502,但是下次访问节点时会继续探测正确节点,直到找到正确的为止。
被动检查
Nginx 的 upstream 模块会实现所谓的被动健康检查,也就是利用 max_fails 机制来实现:
如果请求后端 upstream peer 出现一些错误,当错误的累计次数达到 max_fails,那么该 upstream peer 会被 Nginx 摘掉 fail_timeout 时间,在这个时间内,这个 upstream peer 节点禁止对外提供服务。
需要重点注意的是 fails 是一个区间内失败的累加值,也就是在 fail_timeout 的这个时间区间内,两个错误之间即使有成功的请求,fails 也依然会进行累加计算。
- 如果在 T0 时刻出现了一个错误,那么 fails = 1;
- 在 T0 ~ T0 + fail_timeout 的时间区间内:
- 如果没有出现错误,那么 fails 会重置为 0;
- 如果出现了一个新错误,比如在 T1 时刻出现一个新的错误,那么 fails 会继续累加,fails = 2
- 接着会重新以新的时间区间 T1 ~ T1 + fail_timeout 开始统计但是 fails 值却是继续累加,如果这个时间区间又有一个新的错误,那么 fails = 3
- 直到 T2 时刻,出现了新的错误并 fails >= max_fails,那么 peer 节点会被摘除,在 T2 ~ T2 + fail_timeout 这个时间内,节点就无法对外提供服务,并且重置 fails 为 0,然后开启新的一轮检测
主动检查(未测试)
nginx_upstream_check_module模块(淘宝技术团队开发)
检测后方realserver的健康状态,如果后端服务器不可用,则会将其踢出upstream,所有的请求不转发到这台服务器;当恢复正常时,将其加入upstream
upstream test1 {server 192.168.134.154:80;server 192.168.134.153:80;server 192.168.134.152:80;#每隔5秒检测一次,请求2次正常则标记 realserver状态为up,如果检测5次都失败,则标记 realserver的状态为down,超时时间为1秒,使用http协议。check interval=5000 rise=2 fall=5 timeout=1000 type=http;check_http_send"HEAD / HTTP/1.0\r\n\r\n";check_http_expect_alive http_2xx http_3xx;
}
配置示例
# http contextupstream backend_hosts {server host1.example.com;server host2.example.com;server host3.example.com;
}server {listen 80;server_name example.com;location /proxy-me {proxy_pass http://backend_hosts;}
}
也可以参考192.168.0.135服务器上Nginx的配置
参考
Module ngx_http_upstream_module (nginx.org)
upstream模块 — Nginx开发从入门到精通 (taobao.org)
NGINX — Upstream Module (Part 01) | by Nethmini Romina | FAUN Publication
Understanding Nginx HTTP Proxying, Load Balancing, Buffering, and Caching | DigitalOcean
Nginx 实战系列之四:upstream 的 max_fails 和 fail_timeout 指标和实战经验 - 知乎 (zhihu.com)
Nginx–upstream健康检查 - 心恩惠动 - 博客园 (cnblogs.com)
nginx安装nginx_upstream_check_module模块实现业务平滑转移_三颗草丶的博客-CSDN博客
Nginx之负载均衡upstream模块简介和使用_nginx upstream_普通网友的博客-CSDN博客