我们知道,在单体应用的架构下一旦程序发生了故障,那么整个应用可能就没法使用了,所以我们要把单体应用拆分成具有多个服务的微服务架构,来减少故障的影响范围。但是在微服务架构下,有一个新的问题就是,由于服务数变多了,假设单个服务的故障率是不变的,那么整体微服务系统的故障率其实是提高了的。
比如:假设单个服务的故障率是0.01%,也就是可用性是99.99%,如果我们总共有10个微服务,那么我们整体的可用性就是99.99%的十次方,得到的就是99.90%的可用性(也就是故障率为0.1%)。可见,相对于之前的单体应用,整个系统可能发生故障的风险大幅提升。
那么在这种情况下,我们应该怎么去保证微服务架构的可用性呢?
其实我们参考造船行业对船舱进水风险的隔离方法,如上图。
造船行业有一个专业术语叫做「舱壁隔离」,利用舱壁将不同的船舱隔离起来,如果某一个船舱进了水,那么就可以立即封闭舱门,形成舱壁隔离,只损失那一个船舱,其他船舱不受影响,整个船只还是可以正常航行。
对应到微服务架构中,我们要做的就是最大限度的隔离单个服务的风险,也就是「 容错隔离 」的方法。
在聊「容错隔离」方法之前,我们先来看一下微服务架构中,常见的可用性风险到底有哪些吧,知道了有哪些风险我们才知道该如何去规避、去隔离风险。
我们可以从项目部署规模的角度去分析风险:
好了,上面讲了微服务架构中可能遇到这么多的可用性风险,并且也知道了「容错隔离」的重要性,下面我们再来看看常见的「容错隔离」方法有哪些:
断路器其实就是一个状态机原理,有三种状态:Closed(闭合状态,也就是正常状态)、Open(开启状态,也就是当后端服务出故障后链路断开,不提供服务的状态)、Half-Open(半闭合状态,就是允许一小部分流量进行尝试,尝试后发现服务正常就转为Closed状态,服务依旧不正常就转为Open状态)。
在容错隔离或者说熔断技术方面做得最出名的框架就是 Hystrix 了。Hystrix是由Netflix开源,在业内应用非常广泛。
下面是Hystrix的原理流程图:
这是新版流程,比之前旧版本又复杂很多,如果不讲解一下,估计很多人都不容易看懂。
图中标注了数字1-9,可以按照这个数字顺序去理解这个流程。
当我们使用了Hystrix之后,请求会被封装到HystrixCommand中,这也就是第一步。然后第二步就是开始执行请求,Hystrix支持同步执行(图中.execute方法)、异步执行(图中.queue方法)和响应式执行(图中.observer)。然后第三步判断缓存,如果存在与缓存中,则直接返回缓存结果。如果不在缓存中,则走第四步,判断 断路器 的状态是否是开启的,如果是开启状态,也就是短路了,那就进行失败返回,跳到第八步,第八步需要对失败返回的处理也需要再做一次判断,要么正常失败返回,返回相应信息,要么根本没有实现失败返回的处理逻辑,就直接报错。如果 断路器 不是开启状态,那请求就继续走,进行第五步,判断线程/队列是否满了,如果满了,那么同样跳到第八步,如果线程没满,则走到第六步,执行远程调用逻辑,然后判断远程调用是否成功,调用发生异常了就挑到第八步,调用正常就挑到第九步正常返回信息。
图中的第七步,非常牛逼的一个模块,是来收集Hystrix流程中的各种信息来对系统做监控判断的。
另外,Hystrix的断路器实现原理也很关键,下面就是Hystrix断路器的原理图:
Hystrix通过滑动时间窗口算法来实现断路器的,是以秒为单位的滑桶式统计,它总共包含10个桶,每秒钟一个生成一个新的桶,往前推移,旧的桶就废弃掉。
每一个桶中记录了所有服务调用的状态,调用次数、是否成功等信息,断路器的开关就是把这10个桶进行聚合计算后,来判断当前是应该开启还是闭合的。
以上,就是对微服务架构中「容错隔离」的一些思考。
在微服务架构的系列文章中,前面已经通过文章介绍过了「服务注册 」、「服务网关 」、「配置中心 」、「 监控系统 」、「调用链监控」,大家可以翻阅历史文章查看。
码字不易啊,喜欢的话不妨转发朋友,或点击文章右下角的“在看”吧。?
本文原创发布于微信公众号「 不止思考 」,欢迎关注。涉及 思维认知、个人成长、架构、大数据、Web技术 等。