【未来虫教育】线程隔离浅析

2025-02-25ASPCMS社区 - fjmyhfvclm

前言

随着微服务的流行,单体应用被拆分成一个个独立的微进程,可能一个简单的请求,需要多个微服务共同处理,这样其实是增加了出错的概率,所以如何保证在单个微服务出现问题的时候,对整个系统的负面影响降到最低,这就需要用到我们今天要介绍的线程隔离。

线程模型

在介绍线程隔离之前,我们先了解一下主流容器,框架的线程模型,因为微服务是一个个独立的进程,之间的调用其实就是走网络 io,网络 io 的处理容器如 tomcat,通信框架如 netty,微服务框架如 dubbo,都很好的帮我们处理了底层的网络 io 流,让我们可以更加的关注于业务处理;

Netty

Netty 是基于 java nio 的高性能通信框架,使用了️主从多线程模型,借鉴 Netty 系列之 Netty 线程模型的一张图片如下所示:

为什么要线程隔离

从上面的介绍的线程模型可以知道,处理业务的时候还是使用的 io 线程比如 Tomcat 和 netty,这样会有什么问题那,比如当前服务进程需要同步调用另外三个微服务,但是由于某个服务出现问题,导致线程阻塞,然后阻塞越积越多,占满所有的 io 线程,最终当前服务无法接受数据,直至奔溃;

Dubbo 本身做了 IO 线程和业务线程的隔离,出现问题不至于影响 IO 线程,但是如果同样有以上的问题,业务线程也会被占满;

做线程隔离的目的就是如果某个服务出现问题可以把它控制在一个小的范围,不至于影响到全局;

如何做线程隔离

做线程隔离原理也很简单,给每个请求分配单独的线程池,每个请求做到互不影响,当然也可以使用一些成熟的框架比如 Hystrix (已经不更新了),Sentinel 等;

信号量隔离

线程池隔离的好处是隔离度比较高,可以针对某个资源的线程池去进行处理而不影响其它资源,但是代价就是线程上下文切换的开销比较大,特别是对低延时的调用有比较大的影响;

上面对线程模型的介绍,我们发现 Tomcat 默认提供了 200 个 io 线程,Dubbo 默认提供了 200 个业务线程,线程数已经很多了,如果每个命令在使用一个线程池,线程数会非常多,对系统的影响其实也很大;有一种更轻量的隔离方式就是️信号量隔离,仅限制对某个资源调用的并发数,而不是显式地去创建线程池,所以开销比较小;Hystrix 和 Sentinel 都提供了信号量隔离方式,Hystrix 已经停止更新,而 Sentinel 干脆就没有提供线程隔离,或者说线程隔离是没有必要的,完全可以用更轻量的信号量隔离代替;

总结

本文从线程模型开始,讲到了 IO 线程,以及为什么要分开 IO 线程和业务线程,具体如何去实现,最后简单介绍了一下更加轻量的信号量隔离,为什么说更加轻量哪,其实业务还是在 IO 线程处理,只不过会限制某个资源的并发数,没有多余的线程产生;当然也不是说线程隔离就没有价值了,其实还是要根据实际情况来定,根据你使用的容器,框架本身的线程模型来决定

全部评论