上一篇文章讲到了服务发现,这相当于索引服务,服务被发现之后,就涉及到调用,那么由于微服务自身架构的复杂性,可能因为某一个服务的异常连带导致上层多个服务奔溃,这样的情况我们称为雪崩效应。本文从一个实际场景出发,模拟Hystrix的诞生起因和经过,方便初识Hystrix的朋友更好的理解这个工具。
我们先来看这样一个场景,当我们第一次注册某个电商app后,为了刺激我们消费同时保证用户留存,平台会赠送优惠卷和积分给注册用户;同时一旦积分达到一定数额之后,可以用来兑换优惠卷。我们就以次为例来构建微服务,并讨论一下,这样一个微服务架构可能出现哪些问题,并该如何解决?
新用户注册场景
此时优惠卷服务器部署的当地网络出现故障,优惠卷服务延时很高,用户注册服务发过来的请求需要响应很长时间,资源无法释放,同时大量的用户注册app,导致进入用户注册服务的请求越来越多,这样一来用户注册服务因为资源不足导致崩溃。可见,由于优惠卷服务的网络问题,连带造成用户注册服务崩溃,这显然不是我们想看到的局面,这个时候我们不借助任何框架,来想一下这个问题应该如何解决。
1. 无框架解决方案
-
用户注册服务(以下称为服务1)对优惠卷服务(以下称为服务2)的返回结果及速率有依赖,为了让此依赖不影响服务1的其它正常操作,我们将服务1对服务2的请求放在子线程当中,这样即便子线程中的请求出现异常,主线程仍然不会收到影响。
新线程执行服务间调用 -
通过创建子线程,我们可以保证主线程不受影响。但是这里会衍生出一个问题:进程的子线程数是有限的,当服务2延时导致服务1中线程的创建数大于销毁数,最终会使得服务1计算资源不足,如何解决?
解决这个问题,首先我们必须规范服务1的请求线程上限,否则随着注册人数的增加,线程会急剧增加直至撑爆资源。这里我们定义一个上限为10的线程池,最多同时存在10个赠送优惠卷的请求在路上,这样一来,线程资源可控,服务中其它地方仍有余地申请新的线程资源。
构建线程池机制 -
我们在设计的过程中一步步解决面临的问题,现在线程资源规范过后,一个新的问题出现,在流量很大的情况下,10个线程被占满,这时候有新的请求进来,这个请求去哪里?
当请求进入后发现线程池没有空余线程,这个时候就应该直接进入fallback function(备用方法),这个方法可能是直接返回一个字符串告诉用户正忙或其它默认结果等等。
2. Hystrix解决方案
Hystrix是netflix孵化的一个库,它提供延时容忍、容错机制,避免延时或失败在服务之间传播。Spring Cloud团队将其封装到Spring Cloud Netflix项目当中,为我们的开发提供了更便捷的接口。
同样的还是上面那个例子:用户注册服务、优惠卷服务、积分服务。
网友评论