问题描述
相关组件:
1. WebService:对外提供web接口服务,这里启动了5个(端口分别为:9001-9005)
2. nginx:反向代理5个webService做负载均衡(nginx对外提供9999端口服务)
3. httpclient:调用nginx的9999端口访问webService提供的http接口
timeout设置:
nginx:proxy_read_timeout 设置成了100s
httpclient:timeout默认20s
业务逻辑:
1. httpclient通过nginx的9999端口,调用webservice提供的接口,获取返回的结果,并进行处理。
2. httpclient发生超时时,会自动进行retry,再次调用webService接口。
3. httpclient有多个,用于不同的外部服务
问题复现:
1. 其中一个httpclient调用了webService的一个查询接口(假设对1000万条记录进行全表扫描),执行这个查询的时间远大于30s
2. httpclient在20s时没有收到webService的返回,发生timeout,进行自动retry,再次调用webservice的接口
3. 每次retry被nginx分发到不同的webservice(9001-9005)上去执行,每个webService都被全表扫描阻塞。多次retry后,直接导致所有的webService因为这个请求而阻塞,所有httpclient发送来的请求都超时、retry,陷入恶性循环,雪崩发生。
4. httpclient的超时设置是20s,但是nginx设置的 proxy_read_timeout 为100s,假设 webservice在40s的时候完成查询,并通过nginx返回了结果。但是此时httpclient已经在20s的时候就超时结束了,导致webservice返回的结果并没有收到。
问题分析
这里有三个问题:
1. httpclient超时后,一直retry,nginx会把请求分发到后端的所有webservice里,导致所有webservice全都 去执行全表扫描,无法再对外服务。
2. httpclient的超时设置和nginx的超时设置不一致,导致nginx返回了结果,但是httpclient却始终无法接收 到。
3. webservice被一个全表扫描的请求阻塞时,并没有被nginx的upstream策略剔除,会有新的请求分配到这个webservice,导致新的请求也timeout。
问题解决
对于三个问题,分别的解决方式如下:
1. 对于可能执行全表扫描这种危险操作的请求,通过添加索引等方式进行优化,缩短查询时间,并且禁止进行retry。
2. 将proxy_read_timeout设置成19秒(也就是小于等于httpclient的超时时间),保证超时的统一性。避免httpclient超时,而nginx还没有超时的情况。
3. nginx有max_fails和fail_timeout两个设置,max_fails=1 fail_timeout=120s; 表示server如果在120s内发生一次失败(超时或者拒绝连接)则将该server剔除出去,不再向其分发请求,120秒后再恢复服务。
如下例子:
server 127.0.0.1:9001 max_fails=1 fail_timeout=120s;
server 127.0.0.1:9002 max_fails=1 fail_timeout=120s;
server 127.0.0.1:9003 max_fails=1 fail_timeout=120s;
}
这表示,如果webservice中的server发生一次超时,就停止服务2分钟。2分钟以后再恢复服务。
相关推荐
解决SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded
错误提示: user: ‘root’ host: `localhost’ (Got timeout reading communication packets) MYSQL server has gone away ...这两个值是一个全局变量,可以动态增加,如: mysql> set global interactiv
timeout 又可以细分为 connect timeout、read timeout、write timeout 怎样修改linux操作系统的tcp connect timeout
报错如下 报错: ORA-12170:TNS connect timeout occurred 第一反应是监听没开: 1. 测试了一下, 连接超时没用ping 通 C:\Users\Administrator>tnsping brorcl TNS Ping Utility for 64-bit Windows: Version 11.2...
TIHLDE是 (组织的主要网站)的开源后端。 :rocket: 入门 Lepton需要Python 3.6或更高版本,Docker和Docker Compose。 其他服务由Docker处理。 # Setup a local repository git clone ...
python 使用request时关于timeout参数设置无效和报错遇到的一些问题以及解决(csdn)————程序.
This is proxy server for udp backend servers, with access control, load balance ,timeout , and retransmission. 编译 make clean; make 配置 [global] ;listen directive is used for the address to ...
Rack :: Timeout不能解决长时间运行的请求问题,它是一种调试和修复工具。 应用程序开发人员应跟踪机架超时的数据并解决特定超时的重复实例,例如通过重构代码,使其运行更快或抵消冗长的工作以异步发生。 升级中 ...
介绍浏览器中的对象window的timeout方法window的timeout方法window的timeout方法window的timeout方法window的timeout方法window的timeout方法window的timeout方法window的timeout方法window的timeout方法window的...
基本上,我们捕获 Rack::Timeout 引发的 Exception 并将其转换为 StandardError 以便 Puma 工作人员不会被杀死。 有关问题的更好描述,请参阅 。 基本用法 Rails 应用程序 # Gemfile gem "rack-timeout-puma" 这...
借助淘宝技术团队开发的nginx模快nginx_upstream_check_module来检测后方realserver的健康状态,如果后端服务器不可用,则会将其踢出upstream,所有的请求不转发到这台服务器。当期恢复正常时,将其加入upstream。 ...
windows系统下的python超时装饰器,解决pypi中timeout-decorator库在windows系统上不可用的问题。
超时装饰器安装从源代码: python setup.py install从pypi: pip install timeout-decorator用法import timeimport timeout_decorator@timeout_decorator.timeout(5)def mytest(): print("Start") for i in range(1,...
主要介绍了为jquery的ajax请求添加超时timeout时间的操作方法,文中通过一段简单的代码给大家介绍jquery ajax超时设置方法,感兴趣的朋友跟随脚本之家小编一起看看吧
最近项目中用到了nginx,后台用的是Java, 发现有一个请求后台处理操过了1分钟,结果请求Status Code为504 Gateway Time-out. 理解了下nginx 所有timeout相关的配置,如下: keepalive_timeout HTTP 有一个 KeepAlive...
const Timeout = require ( 'koa-better-timeout' ) ; // ... const timeout = new Timeout ( ) ; app . use ( timeout . middleware ) ; 具有转换后的响应消息的高级中间件用法(例如,使用及其中间件): const...
本文介绍 Nginx 的 超时(timeout)配置。分享给大家,具体如下: ...HTTP 有一个 KeepAlive 模式,它告诉 webserver 在处理完一个请求后保持这个 TCP 连接的打开状态。若接收到来自客户端的其它请求,服务端会利用这
关于MySQL的wait_timeout连接超时问题报错详细解决方案
Java后端常用工具类、缓存接口、消息队列接口、第三方支付接口封装;Restful接口参数验证,错误信息友好提示。 [TOC] 1.分布式锁、分布式方法锁(common-distributed-lock): DistributedLock类(依赖RedisTemplate...
hair-time-backend:后端头发时间