微服务中的“服务降级”,这样解释满意吗?
问题描述:为什么一个异常服务会拖垮整个公司的所有服务?
总结先提炼——我们需要甄别“正常服务”与“异常服务”,并且对“异常服务”进行降级。
假设服务A为公司对外暴露的服务集群,它有以下调用链:
A-->B-->...-->...-->X
A-->C-->...-->...-->Y
A-->D-->...-->...-->Z
如上所示,对外暴露的服务集群A最终将调用 X、Y、Z 等几种数据源拿到数据,来为不同的对外接口服务,而与对外服务A直接关联的有 B、C、D 等几种内部服务。
假设此时服务B发生异常,A-->B-->...-->X 整个调用链都会卡在服务B提供的接口上,不管是 A-->B-->C-->...-->X 或者 A-->B-->D-->...-->X 也好,总之以 A-->B 起头的调用链都像发生了异常一样,其他 A-->C 和 A-->D 调用链没有问题。
此时我们需要考虑时间因素
公平起见假设外部调用者的接口调用是随机的,那么原本访问 B、C、D三种类型的接口次数是均匀分配的,在这个假设前提下经过C和D的请求没有问题,在合理时间内响应并返回,而访问到B的请求将会卡住。经过一段时间后,由于服务B异常导致A-->B 这条请求线路上卡住的请求越来越多,服务A上的资源将因为服务B的异常耗尽,而原本没有问题的“正常服务集C和D”也被服务B的影响了,通过A-->B这条请求链间接影响,最终导致整个对外服务都发生异常。
前面说的是“公平起见,访问B、C、D三种类型接口的次数是平均的”,而在不平均的情况下,比如100次接口访问,98次访问了B这个类型的接口,1次C类型接口、1次D类型接口,这种情况下服务A瘫痪的速度会更快。
服务降级小结
所以,对外暴露的服务,需要能够甄别其使用的内部服务集中哪些是“正常服务”与“异常服务”,并在服务发生异常时,及时将该服务降级,避免最终瘫痪掉整个对外服务。
Spring cloud 的 Netflix 套件中正好有一个用于服务降级组件:断路器 Hystrix
如果没有相关知识储备的,可以看一下这位大佬的spring cloud专题:http://blog.didispace.com/spring-cloud-learning/,里面各类spring cloud组件的博文都给你总结好了,当然也有 Hystrix。
服务降级思维发散
不仅是外部服务与内部服务之间需要“降级”手段,还有许多关键的服务间调用也需要类似“降级”的手段来保证服务的可用性。甚至操作系统级别的调用也有“降级”的影子:在没有调过参数的linux服务器上,面对海量TCP并发连接时,将会有大量连接被直接拒绝连接,根本都不需要进行“三次握手”。操作系统通过拒绝连接的方式(类似降级),使得最先进去的那一批连接最终能够正常被服务,保证了一定的可用性。