因资源用尽导致服务宕机

1. 事故的发生

服务调用场景和发生的事件如下图所示,红色表示服务不可用. 第一个事件第二个事件

服务A服务B都是内部服务,服务C_*为不同运营商提供的服务,遵循一样的协议。
某一天,突然发现所有服务A调用服务B的请求都被熔断了。去服务器上看下,发现服务B依然运行。日志不再打印,最近的日志都是调用服务C_3请求超时。尝试了下重启,2,3分钟后服务又处于不可用状态。

1.1 查找原因

第一时间想到了发生了死锁,立刻使用jstack查看一下,(忘记截图保存资料了)。
发现是RestTemplate里有线程处于wait状态,联想到爆出的服务C_3服务处于宕机状态,立刻想到了httpClient里配置的最大连接被占满,而且没有配置当连接数占满后的等待超时时间,导致其他请求处于一直等待状态!而正在使用的连接,因为请求服务C_3超时(当时配置了超时时间10s)....
当然故障的主要原因不仅于此,还有重试机制!当请求失败后,会间隔5s后重试,所以服务B的不可用状态不仅是因为新的请求而阻塞,主要原因是大量的重试。

1.2 临时的解决方案

  1. 立刻清除掉所有关于服务C_3的重试任务,清除掉后,服务B恢复正常。
  2. 缩短请求超时时间。因为协议约定接口是异步通知的方式,所以超时时间不应过长

2. 应该做的

调用外部的服务,我们是通过同一个RestTemplate实例做的,这是个错误

2.1 资源应该是隔离的

就像船舱一样,底部的船舱都会分隔成写小舱室,每个小舱室都可以做到完全隔离,以此确保某个舱室漏水时保证整个船是安全的。
同理,针对多个服务C_*,他们之间的资源应该是隔离的,都有不同的RestTemplate实例

2.2 快速的失败机制

如果单个服务C_*宕机后,在人工未介入前,应该在一定时间内,再请求该服务应该是快速失败,不阻塞。

3. 总结

其实这个教训主要来自于资源的滥用和当服务出现故障后没有熔断机制。

服务_c*属于外部服务,并没有按照spring cloud的开发方式去做,现在看来,哪怕不按照spring cloud的去做,也要参考一些它的机制。
防雪崩利器:熔断器 Hystrix 的原理与使用

转载于:https://my.oschina.net/northerSong/blog/3004956

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值