记录:解决后端server因一个timeout导致的雪崩


问题描述

相关组件:

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

 

伦理片 http://www.dotdy.com/

业务逻辑:

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。

 

 

问题解决

对于三个问题,分别的解决方式如下:

 影音先锋电影 http://www.iskdy.com/ 

1. 对于可能执行全表扫描这种危险操作的请求,通过添加索引等方式进行优化,缩短查询时间,并且禁止进行retry。

 

2. 将proxy_read_timeout设置成19秒(也就是小于等于httpclient的超时时间),保证超时的统一性。避免httpclient超时,而nginx还没有超时的情况。

 

3. nginx有max_fails和fail_timeout两个设置,max_fails表示server如果发生一次失败(超时或者拒绝连接)则将该server剔除出去,不再向其分发请求。fail_timeout表示多少秒后恢复服务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值