项目架构:nginx+php fpm 负载均衡
负载均衡关键配置如下:
#引入负载均衡配置
include proxy.conf;
#负载均衡
upstream test_balance {
server 172.28.196.xxx:80 weight=100; #远端服务
server 127.0.0.1:20000 weight=100;
keepalive 256;
}
出现问题:
当某个php服务报错后,整个负载均衡返回502,并且非报错接口同样返回502,问题非常严重,因为php的优势就是解析执行,不相干代码应该不会干扰才对,但上负载后出现 只要整个项目某个接口返回500,短时间内所有接口都会返回502
解决:
一:设置 max_fails=1 跟 fail_timeout=1
max_fails默认值为1,fail_timeout默认值为10秒。
nginx可以通过设置max_fails(最大尝试失败次数)和fail_timeout(失效时间,在到达最大尝试失败次数后,在fail_timeout的时间范围内节点被置为失效,除非所有节点都失效,否则该时间内,节点不进行恢复)对节点失败的尝试次数和失效时间进行设置,当超过最大尝试次数或失效时间未超过配置失效时间,则nginx会对节点状会置为失效状态,nginx不对该后端进行连接,直到超过失效时间或者所有节点都失效后,该节点重新置为有效,重新探测.
通过上面可知道,返回502原因就是所有节点都探测失败,但是没到失效时间(10s),这样10s内所有访问都将被返回502(没有节点可用)
通过设置 fail_timeout=1 让nginx 在1s后自动刷新节点状态,也就是只要1s后不报错的接口是可以正常访问的,之前默认是要10s,就是一个接口报错 整个项目10s内都是502!
修改后配置如下:
#负载均衡
upstream test_balance {
server 172.28.196.xxx:80 max_fails=1 fail_timeout=10 weight=100; #远端服务
server 127.0.0.1:21688 max_fails=1 fail_timeout=10 weight=100;
keepalive 256;
}
第二:修改proxy.conf 里的 proxy_next_upstream 配置,使后端返回500 状态不标记为失败
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时,则该节点失效。
修改后 proxy.conf 配置
proxy_temp_path /www/server/nginx/proxy_temp_dir;
proxy_cache_path /www/server/nginx/proxy_cache_dir levels=1:2 keys_zone=cache_one:20m inactive=1d max_size=5g;
client_body_buffer_size 512k;
proxy_connect_timeout 60;
proxy_read_timeout 60;
proxy_send_timeout 60;
proxy_buffer_size 32k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_next_upstream error timeout invalid_header http_503 http_404;
proxy_cache cache_one;
修改完后 php 报错将不再出现502,问题解决