一 netty的線程模型
在netty中存在兩種線程:boss線程和worker線程。
1 boss線程
作用:
- accept客戶端的連接;
- 將接收到的連接注冊到一個worker線程上
個數:
- 通常情況下,服務端每綁定一個端口,開啟一個boss線程
2 worker線程
作用:
- 處理注冊在其身上的連接connection上的各種io事件
個數:
- 默認是:核數+1
注意:
- 一個worker線程可以注冊多個connection
- 一個connection只能注冊在一個worker線程上
二 dubbo的事件派發策略和線程池
1、dubbo基於netty。有5種派發策略:
- 默認是all:所有消息都派發到線程池,包括請求,響應,連接事件,斷開事件,心跳等。 即worker線程接收到事件后,將該事件提交到業務線程池中,自己再去處理其他事。
- direct:worker線程接收到事件后,由worker執行到底。
- message:只有請求響應消息派發到線程池,其它連接斷開事件,心跳等消息,直接在 IO線程上執行
- execution:只請求消息派發到線程池,不含響應(客戶端線程池),響應和其它連接斷開事件,心跳等消息,直接在 IO 線程上執行
- connection:在 IO 線程上,將連接斷開事件放入隊列,有序逐個執行,其它消息派發到線程池。
2、業務線程池:
- fixed:固定大小線程池,啟動時建立線程,不關閉,一直持有。(缺省)
- coresize:200
- maxsize:200
- 隊列:SynchronousQueue
- 回絕策略:AbortPolicyWithReport - 打印線程信息jstack,之后拋出異常
- cached:緩存線程池,空閑一分鍾自動刪除,需要時重建。
- limited:可伸縮線程池,但池中的線程數只會增長不會收縮。只增長不收縮的目的是為了避免收縮時突然來了大流量引起的性能問題。
三 服務端
兩種線程池:
- io線程池:netty的boss和worker線程池。
- boss:建立connection
- worker:處理注冊在其身上的連接connection上的各種io事件
- 業務線程池:fixedThreadPool():“DubboServerHandler-10.10.10.11:20880” 見“二 dubbo的事件派發策略和線程池”
- 與worker配合處理各種請求
四 客戶端
兩種線程池:
- io線程池:netty的boss和worker線程池
- 同上
- 業務線程池:cachedThreadPool:“DubboClientHandler-10.10.10.10:20880”
- 與worker配合處理各種響應,最后得到響應后喚醒被阻塞的主線程
五 dubbo線程模型圖
整體步驟:(受限於派發策略,以默認的all為例, 以netty4為例)
- 客戶端的主線程發出一個請求后獲得future,在執行get時進行阻塞等待;
- 服務端使用worker線程(netty通信模型)接收到請求后,將請求提交到server線程池中進行處理
- server線程處理完成之后,將相應結果返回給客戶端的worker線程池(netty通信模型),最后,worker線程將響應結果提交到client線程池進行處理
- client線程將響應結果填充到future中,然后喚醒等待的主線程,主線程獲取結果,返回給客戶端