问题背景
在做苏宁易购拍卖平台的时候,设计了一套推送服务器,只有一个只读json接口。原理是使用了发布订阅模式,所有数据都缓存到了tomcat中,向推送服务器写入数据走的是另外一套业务系统,并不是从推送服务器写入。每次请求到来不需要任何远程读取,tomcat中直接返回。在虚拟机上(4c)上做了性能测试,TPS在7000#/sec左右波动,响应时间是平均4ms。理论上这是一个很强大的模块,或者说是系统。但是生产通过监控平台发现,有个别请求用了200多秒,让人费解。问题跟踪了很久,也尝试过很多办法,例如tomcat的超时时间等,都没有效果。最后定位到问题,通过设置nginx的失效策略,等待后端app服务器超时解决。
处理办法
反向代理
将apache更换成nginx,推送服务器只有一个只读json接口,切换后调试方便,出错概率极低。
失效策略
服务器500错误的参考文章:http://jingyan.baidu.com/article/63f2362812cc600208ab3dce.html
如果后端tomcat服务器处理超时,则nginx不请求下一个tomcat节点,而是直接返回。nginx默认,会重复尝试所有的节点以后,才会返回给浏览器错误。例如:在location设置参数(默认值也是如此):
proxy_next_upstream http_502 http_504 error timeout invalid_header;
其中有一个参数值 timeout,这个参数代表如果超时,则尝试其他节点。因此要去掉这个参数,修改后如下
proxy_next_upstream http_502 http_504 error invalid_header;
超时时间
因为通过性能测试,响应平均时间是4ms,因此设置1s的等待时间足矣。所以后端一旦出现超时,雪崩效应即将产生,转发给别的节点也是没用的,所以此处的降级方案启动,直接返回错误即可。在location设置参数:proxy_read_timeout;
这个参数表示nginx等待单个后端应用服务器响应的等待时间。最终配置如下
proxy_read_timeout 1;
最终结论
proxy_read_timeout 1;
proxy_next_upstream http_502 http_504 error invalid_header;
看图
具体的配置文件,也在附件中,供参考。
陷阱
proxy_read_timeout 1;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
这个设置和上面的结论就差个timeout,这样设置的话,假设一个nginx后面挂了40个tomcat,那么浏览器要等40秒才能超时!切记。
参考文章
http://bbs.51cto.com/thread-1137613-1.html
http://myhat.blog.51cto.com/391263/1117381/
http://my.oschina.net/greki/blog/109643
http://onlyzq.blog.51cto.com/1228/557848/
nginx的超时设置
http://blog.csdn.net/liujiyong7/article/details/18228915
http://www.cnblogs.com/discuss/articles/1866851.html
tomcat超时时间
http://www.360sdn.com/tomcat/2014/0221/2387.html