從微博motan看rpc基於netty4遠程通訊設計4-同步非同步返回結果處理
微信公眾號:winter分享匯
如有問題或建議,請公眾號留言
從微博motan看rpc基於netty4遠程通訊設計4-同步非同步返回結果處理
本系列文章-連載中
同步非同步返回結果處理
RPC發送請求,客戶端代理對象網路流寫完以後,發消息與讀消息在不同的線程,此時代理對象需要獲取服務端的響應信息返回給調用者,
服務端返回結果怎麼獲取?怎麼進行線程間通訊?帶著這種疑問,我們看下motan是怎麼設計的.
我們先來看客戶端的request設計
可以看到有個DefaultRequest有個requestId的屬性,那麼這個requestId在哪裡設置的呢?我們接著看RPC的代理Handler
可以看到,有個全局生成id的工具類,客戶端每次請求,都會給當前請求報文設置一個請求id,接著又想,這個requestId有何作用呢?
通過NettyClient我們發現,有個map存儲requestId對應的ResponseFuture,那麼這個ResponseFuture有何作用呢?何時放入
map,何時移除?我們翻看NettyChannel的request方法
在request開始的時候會初始化DefaultResponseFuture然後存入map中,當netty write成功,會記錄結果,失敗則從map中移除
response,我們知道netty所有的操作都是非同步的,此時返回了response只是初始化的,並沒有服務端的消息,程序還會往下走,那在
哪裡阻塞等待伺服器響應的呢?我們翻看motan客戶端的代理方法AbstractRefererHandler的
我們看這裡的response就是上面說到的DefaultResponseFuture,如果是非同步請求,則直接就響應調用方.如果是同步請求則會response.getValue()
獲取服務端響應的結果,重點在這裡,此時這裡會阻塞,我們翻看DefaultResponseFuture的源碼
我們看到此時線程進入等待狀態了,那當服務端響應消息後,誰來喚醒調用線程讓其響應調用方呢?,我們翻看NettyClient的MessageHandler實現
接收到服務端返回的消息後,會從map移除ResponseFuture,並且執行onFailure或者onSuccess方法,我們翻看onSuccess實現
done方法會喚醒正在等待服務端返回結果的調用方線程.
下一篇:從微博motan看rpc基於netty4遠程通訊設計5-協議編解碼與序列化
下面的是我的公眾號二維碼圖片,歡迎關注我。
圖注:winter分享匯
TAG:全球大搜羅 |