0x00 ngx_http_upstream_module
Nginx
负载通过 ngx_http_upstream_module 模块来实现,通过定义一组机器来实现负载均衡.
其中一个配置实例为:
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://backend;
}
}
0x01 upstream 指令
upstream name{...}
定义一组server
,通过不同的均衡算法来选择访问的server
server address[parameters]
每台server
可以配置不同的 ip 和端口,可选的参数为:
weight=number
设置server
的权重,默认为 1max_conns=number
限制到server
的最大连接数,默认为 0 不限制max_fails=number
设置该server
在fail_timeout
参数设置的持续时间内与服务器通信的可失败数,达到数量后该server
将被置为不可用.默认为 1,0 为不限制.被认为失败的请求将被proxy_next_upstream,fastcgi_next_upstream,uwsgi_next_upstream,scgi_next_upstream和memcached_nex_upstream处理fail_timeout=time
默认为 10sbackup
将server
置为备用,当主服务器不可用时启用down
将server
显示标志为永久不可用resolve
监听服务器 ip 的变化,在不用重启 nginx 的情况下自动修改upstream
配置.要启用该项必须将配置读入共享内存中,同时必须在http
中写入解析指令eg.1route=string
设置server
路由名称service=name
slow_start=time
设置慢启用时间,在该时间内server
对应的权重将从0恢复到weight
值,但是该配置不能和hash
/ip_hash
负载方法同时启用
http {
resolver 10.0.0.1;
upstream u {
zone ...;
...
server example.com resolve;
}
}
state file
指定动态配置服务器分组的配置文件,例如:
state /var/lib/nginx/state/servers.conf; # path for Linux
0x02 负载方法
nginx
默认的负载方式为轮训,其他的负载方法为:hash
,ip_hash
,fair
,url_hash
.
hash key[consistent]
如果指定了一致的参数consistent
,将使用 ketama 一致性散列法。该方法确保在向组中添加或从组中删除服务器时,只有少量密钥将重新映射到不同的服务器。这有助于实现缓存服务器的更高的缓存命中率。
ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
0x03 问题
最近运营后台上线之后,接到反馈发现低概率出现 502 错误.但是运营后台有两台 web 服务器,通过 nginx 负载,服务器的访问量也很低,完全没有性能问题.虽然有一些耗时的操作,但不会对服务器造成较大的压力.检查了下代码层也没有发现返回内容时将 http_code 置为 502 的操作.
晚上跟运维排查了下发现每次有 502 返回的时候,对应的 ngx 日志里都轮训了两台 web 服务器,这说明当时两台 web 服务器处于不可用状态.近一步检查发先 502 请求之前,会有数个超时的请求,最终导致该请求失败.所以综合可发现数个超时的请求短时间内出现,nginx 将两台机器置为不可用.当再有新的访问进来时,遍历两台 web 服务器发现都不可用,最后只能返回 502,这也就是为什么出现 502 错误的时候,响应时间都很快的原因.
临时的修改方法是对每台服务器,设定一个较大的max_fails
值,虽然治标不治本,但是先保证服务可用.