背景
在使用dubbo rpc调用时,使用异步操作提供并发的两种操作,异步调用和异步执行。
一、异步调用
-
异步调用是我们平时可能最容易理解也是使用最多的情况。当我有多个rpc接口要调用的时候,我可以开启一个线程池,这样就能做到并发,或者是在dubbo的异步配置中配置上async让其返回一个CompleteFuture。
二、异步执行
-
异步执行,在dubbo的应用反而很少。
个人认为,理解异步化有个前提,就是要区分两个线程:请求处理主线程&业务异步子线程:
- 请求处理主线程:由 Dubbo 框架提供,主要用于接收 RPC 请求。线程池大小默认为200。
- 业务异步子线程:由业务自定义,可设置线程池大小、队列长度、拒绝策略等,用于异步执行业务逻辑。 异步化的核心思想在于,将本来需要由主线程来执行的耗时操作,交给异步子线程来执行,使得主线程可以快速执行完成,避免 Dubbo 线程池被耗尽导致服务不可用。站在调用方的角度来看,实际请求的执行时间并没有缩短,但是服务整体的吞吐量是有很大的提升的。
- 其次可以这么理解,提供方的异步化旨在提高吞吐量,说白了就是用自己的线程池去承处理业务,以此来释放Dubbo框架本身的线程去处理其他耗时比较短的请求,就有点类似于脏活累活交给一个特定的线程池让它自己扛,能扛多少是多少,既轻松又快的活Dubbo自己干,见缝插针似的尽可能提升提供方的整个吞吐。
- 最后如果是这种慢请求打到单机瓶颈了那还真得好好看看优化,如果是那种耗时非常短的请求打到单机瓶颈了,那你得后续考虑加大Dubbo本身线程核心数据或扩容或者有损限流降级等等之类的了。