2.1.3 服务的容错
微服务落地到实际项目中,服务的数量往往非常多,服务之间的相互依赖性也是错综复杂的,一个网络请求通常需要调用多个服务才能完成。如果一个服务不可用,例如网络延迟或故障,会影响到依赖于这个不可用的服务的其他服务。如图2-4所示,一个微服务系统有很多个服务,当服务F因某些原因导致了服务的不可用,来自于用户的网络请求需要调用服务F。由于服务F无响应,用户的请求都处于阻塞状态,在高并发的场景下,短时间内会导致服务器的线程资源消耗殆尽。另外,依赖于服务F的其他的服务,例如图中的服务E、服务G、服务J,也会等待服务F的响应,处于阻塞状态,导致这些服务的线程资源消耗殆尽,进而导致它们的不可用,以及依赖于它们的服务的不可用,最后导致整个系统处于瘫痪的状态也就是1.2.1节中提到的雪崩效应。
▲图2-4 服务的依赖性
为了解决分布式系统的雪崩效应,分布式系统引进了熔断器机制。熔断器(Circuit Breaker)一词来源于物理学中的电路知识,它的作用是当电路中出现故障时迅速切断电路,从而保护电路,熔断器机制如图2-5所示。当一个服务的处理用户请求的失败次数在一定时间内小于设定的阀值时,熔断器处于关闭状态,服务正常;当服务处理用户请求的失败次数大于设定的阀值时,说明服务出现了故障,打开熔断器,这时所有的请求会执行快速失败,不执行业务逻辑。当处于打开状态的熔断器时,一段时间后会处于半打开状态,并执行一定数量的请求,剩余的请求会执行快速失败,若执行的请求失败了,则继续打开熔断器;若成功了,则将熔断器关闭。
▲图2-5 熔断器机制
这种机制有着非常重要的意义,它不仅能够有效地防止系统的“雪崩”效应,还具有以下作用。
•将资源进行隔离,如果某个服务里的某个API接口出现了故障,只会隔离该API接口,不会影响到其他API接口。被隔离的API接口会执行快速失败的逻辑,不会等待,请求不会阻塞。如果不进行这种隔离,请求会一直处于阻塞状态,直到超时。若有大量的请求同时涌入,都处于阻塞的状态,服务器的线程资源,迅速被消耗完。
•服务降级的功能。当服务处于正常的状态时,大量的请求在短时间内同时涌入,超过了服务的处理能力,这时熔断器会被打开,将服务降级,以免服务器因负载过高而出现故障。
•自我修复能力。当因某个微小的故障(例如网络服务商的问题),导致网络在短时间内不可用,熔断器被打开。如果不能自我监控、自我检测和自我修复,那么需要开发人员手动地去关闭熔断器,无疑会增加开发人员的工作量。
Netflix的Hystrix熔断器开源组件功能非常强大,不仅有熔断器的功能,还有熔断器的状态监测,并提供界面友好的UI,开发人员或者运维人员通过UI界面能够直观地看到熔断器的状态和各种性能指标。