微服务的战争:级联故障和雪崩

Go语言精选

共 1363字,需浏览 3分钟

 ·

2020-09-02 05:02

“微服务的战争” 是一个关于微服务设计思考的系列题材,主要是针对在微服务化后所出现的一些矛盾/冲突点,不涉及具体某一个知识点深入。如果你有任何问题或建议,欢迎随时交流。

在《微服务的战争:统一且标准化》中,经过好几周与不同业务组不同事业部的跨部门讨论后,终于把初始的标准化方案给定下来了。

大家欢快的使用起了内部的统一框架,疯狂的创建起了新服务,没隔多久服务调用链就变成了下图:


服务间存在多次内部调用,服务 A =》服务 B =》服务 C =》服务D,而 服务 E =》 服务 B,服务 F =》服务 E,也就是存在着多个流量入口,且依赖相同的服务。

背景

服务与服务中,总存在业务服务,公共服务,基础服务等类型。但在某一个夜晚,突然发现 BFF 调用后端服务开始逐渐不正常,客户给你截图反馈问题,你发现有点问题:


单从表现来看,你发现是 BFF 调用服务 A 极度缓慢,也不知道怎么了...正当以为是服务 A 出问题,想着万能重启一下时。你在日志平台和链路追踪系统一看,发现了大量的错误日志和缓慢,让你略微震惊,一时间不知道从何下手。

这可怎么办?

级联故障和雪崩

实际上这是一次很经典的级联故障,最终导致系统雪崩的情景再现。单从上述拓扑来看,问题点之一在于服务 B:


服务 B 本身作为服务 A 和服务 F 的两个流量入口必经之处,想必至少是一个公共服务,但他也依赖了其他多个服务。因此若服务 C 和服务 D 其中一个有问题,在没有熔断措施的情况下,就出现级联故障,系统逐渐崩盘,最后雪崩:


服务 D 所依赖的外部接口出现了故障,而他并没有做任何的控制,因此扩散到了所有调用到他的服务,自然也就包含服务 B,因此最终出现系统雪崩。

这种最经典的是出现在默认 Go http client 调用没有设置 Timeout,从而只要出现一次故障,就足矣让记住这类 “坑”,毕竟崩的 ”慢“,错误日志还多。

解决方法

常见的方式是根据特定的规则/规律进行熔断和降级,避免请求发生堆积:

  • 超时时间控制。

  • 慢调用比例。

  • 错误比例。

  • 自适应(例如:负载情况等)。

当然,这也只是壮士断腕,后续措施还包含监控告警,通知对应的开发人员来处理。且需提前对被降级的模块进行业务逻辑进行处理等等,这样才能够比较柔和且快速地度过这一次危机。

总结

在分布式应用中,级联故障和雪崩是非常常见的,一些开发同学在模块设计时可能并没有意识到这块的问题,在微服务化后会一个不留神就碰到,因为其调用链变得特别的长且多。因此建议配套设施和限流熔断措施都应该及时跟上,否则面对一大堆的错误日志还是很无奈的。


同时,监控告警的建设也要做,因为在危机出现时,有一个 HTTP 调用的 P95/P99 告警出现,那就比较舒心了,直接 root cause。





推荐阅读



学习交流 Go 语言,扫码回复「进群」即可


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注


浏览 34
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报