1、参考
线程模型:http://dubbo.apache.org/en-us/docs/user/demos/thread-model.html
2.1、线程模型
官网示意图:
我个人觉得这个图可能画错了,左边的Proxy与Client是不是应该倒换一下。
关于线程模型的几个点:
- 如果任务不包括耗时操作如各种I/O或者是大量的计算,只在内存中就可很快完成,则任务应该由I/O线程直接执行,而不是分发给线程池。本质上就是I/O线程工作在非阻塞模式,当I/O没有就绪时,线程无事可干,顺道处理一些小任务。
- 如果任务需要耗时的I/O操作,或者计算量很大,则应该分发给线程池。如果I/O线程处理此类任务,就会耽误它的主业,就是从网络上读写数据。
- 如果用 IO 线程处理任务,又在任务处理过程中发起新的 IO 请求,比如在连接事件中发起登录请求,会报“可能引发死锁”异常,但不会真死锁。直接点说,如果任务在处理过程中会发起新的I/O请求,那么,一定要把它交给线程池处理就行了。
Dubbo中线程模型的配置两个主要的方面,一个是配置Dispather,决定这个任务应该由I/O线程或者线程池谁来处理。第二个就是线程池的一些参数,初始多少线程、最大多少、最小多少等。示例:
<dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" />
dispatcher的取值,发现一个事,配置里是dispacher这个词,上图中写的是dispather。
- all: 请求全部交给线程池。
- direct: 请求全部由I/O线程处理。
- message: 原文(Only request, response messages will be dispatched to I/O thread.),应该是写错了,只有request、response消息分发给线程池,其它如disconnect, connect, heartbeat等由I/O纯种处理。
- execution: 只有request消息分发给线程池,其它一律I/O线程。
- connection: I/O线程也有一个对列,把disconnect、connect任务放在队列里,有空的时候去处理一下,其它一律线程池。
threadpool取值:
fixed
固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)cached
缓存线程池,空闲一分钟自动删除,需要时重建。limited
可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。eager
优先创建Worker
线程池。在任务数量大于corePoolSize
但是小于maximumPoolSize
时,优先创建Worker
来处理任务。当任务数量大于maximumPoolSize
时,将任务放入阻塞队列中。阻塞队列充满时抛出RejectedExecutionException
。(相比于cached
:cached
在任务数量超过maximumPoolSize
时直接抛出异常而不是将任务放入阻塞队列)