及联问题是一个很严重的问题,它的现象是多个业务共用一个资源池,如果其中一个业务访问外部系统,当外部系统响应缓慢,且访问量大的时候,这个业务会占用所有的资源池 ,导致其它所有的业务都无法工作。
在微服务中,由于服务越来越多,从概率上说,其中某个服务发生概率的情况就越来越大。对于每个对其它服务的请求,我们都要考虑它可能会出问题,设计时考虑会不会产生及联问题,和发生了应该怎么处理,之前我在工作中就出现过一个类似的情况。
项目使用springboot作为微服务的框架,用@Async做统一的线程池管理去处理所有的异步处理和外部系统调用,包括短信系统的请求,推送系统的请求等。有一天线上客户反馈接受不到短信通知,好在日志打的比较详细,发现数据正常,但是没有调用短信系统的请求日志。由于代码一直执行的很好,认为不是代码的问题,可能是线程池堆积了其它调用任务。仔细检查外部调用日志,发现是某个政府的接口的请求任务很多,而且请求存在操时情况。考虑这个外部请求只会在一些极少数的校验业务中出现,不是主要业务,于是我们停掉了这个政府接口调用,重新分步上线,问题就得到了解决,用户可以收到短信了。之后我们对系统的外部系统请求都做了一个断路器(超时阀值),如果超时数过多,就在一个时间断不执行这个外部请求,直接返回请求失败,就好像保险丝一样,不能让一个外部请求导致整个业务都不可用。
在微服务的架构中,某个外部请求不可用造成堵塞任务,耗尽资源的情况一定会出现,就可以采用断路器来解决这种问题。
上面问题还可以使用舱壁来解决,即每个外部调用都用自己独立的线程池,线程池之间互不干扰,但这样的缺点是浪费资源,会有大量的线程,而且随着业务的开发,人员的变更,大家都不知道这个项目开了多少个线程池。