Spring cloud:RPC保护之舱壁模式

        什么是舱壁模式船舶工业为了使船不容易沉没,使用舱壁将船舶划分为几个部分,以便在船体破坏的情况下可以将船舶各个部分密封起来。泰坦尼克号沉没的主要原因之一就是它的舱壁设计不合理,水可以通过上面的甲板进入舱壁的顶部,导致整个船体淹没。在RPC调用过程中,使用舱壁模式可以保护有限的系统资源不被耗尽。在一个基于微服务的应用程序中,通常需要调用多个服务提供者的接口才能完成一个特定任务。不使用舱壁模式,所有的RPC调用都从同一个线程池中获取线程,一个具体的实例如图所示。在该实例中,服务提供者Provider A对依赖的Provider B、Provider C、Provider D的所有RPC调用都从公共的线程池获取线程。

                                                          公共的RPC线程池

        在高服务器请求的情况下,对某个性能较低的服务提供者的RPC调用很容易“霸占”整个公共的RPC线程池,对其他性能正常的服务提供者的RPC调用往往需要等待线程资源的释放。最后,整个Web容器(Tomcat)会崩溃。现在假定ProviderA的RPC线程个数为1000,且并发量非常大,其中有500个线程来执行Provider B的RPC调用,此时剩下的服务Provider C、Provider D总共可用的线程为500个。如果Provider B不小心宕机了,那么这500个线程都会超时,随着并发量的增大,剩余的500个线程估计也会被Provider B的RPC耗尽,然后Provider A进入瘫痪状态,最终导致整个系统的所有服务都不可用,这就是服务的雪崩效应。为了最大限度地减少Provider之间的相互影响,一个更好的做法是:对于不同的服务提供者可以设置不同的RPC调用线程池,让不同RPC通过专门的线程池请求到各自的Provider服务提供者,像舱壁一样对Provider进行隔离。对于不同的服务提供者设置不同的RPC调用线程池,这种模式被称为舱壁模式,如图所示

 舱壁模式的RPC线程池

        使用舱壁可以避免对单个Provider的RPC消耗掉所有资源,从而防止由于某一个服务性能低而引起的级联故障和雪崩效应。在Provider A中,假定对服务Provider B的RPC调用分配专门的线程池Thread Pool B,其中有10个线程,只要对ProviderB的RPC并发量超过10,后续的RPC就降级服务,即使服务Provider B挂了,最多导致Thread Pool B不可用,而不会影响系统中对其他服务的RPC。一般来说,RPC线程与Web容器的IO线程也是需要隔离的。如图5-6所示,当Provider A的用户请求涉及Provider B和Provider C的RPC时,Provider A的IO线程会将任务交给对应的RPC线程池里面的RPC线程来执行,Provider A的IO线程就可以去干别的事情去了,当RPC线程执行完远程调用的任务之后,就会将调用的结果返回给IO线程。如果RPC线程池耗尽了,IO线程池也不会受到影响,从而实现RPC线程与Web容器的IO线程的相互隔离。

 RPC线程与Web容器的IO线程相互隔离

        Hystrix提供了两种RPC隔离方式:线程池隔离和信号量隔离。由于信号量隔离不太适合使用在RPC调用的场景,因此这里重点介绍线程池隔离。虽然线程在就绪状态、运行状态、阻塞状态、终止状态间转变时需要由操作系统调度,这会带来一定的性能消耗,但是Netflix详细评估了使用异步线程和同步线程带来的性能差异,结果表明在99%的情况下异步线程带来的延迟仅仅几毫秒,这种性能的损耗对于用户程序来说完全是可以接受的。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值