聊聊dubbo協議2

捉蟲大師發表於2022-01-19

本文已收錄 https://github.com/lkxiaolou/lkxiaolou 歡迎star。

《聊聊dubbo協議》中介紹了attachments在consumer和provider間的傳遞情況,有個疑問沒有給出答案。

為什麼2.7.x版本的dubbo不支援provider端向consumer端回傳隱式引數呢?今天的續集將揭曉答案。

抓包確定是provider沒發還是consumer丟掉

以下測試基於dubbo 2.7.6版本

在provider端加入下面的程式碼

RpcContext.getServerContext().setAttachment("hello", "from_provider");

執行provider,並用consumer不斷地呼叫,同時進行抓包

sudo tcpdump -i any -vv -A -n port 20880

可以看到provider端將我們的引數回傳了回去,說明是consumer端將資料“弄丟了”

image

分析2.6.x與2.7.x程式碼的差別

consumer在收到provider的請求返回時,處理流程如下:

DecodeableRpcResult->decode->case DubboCodec.RESPONSE_VALUE_WITH_ATTACHMENTS->handleAttachment

image

斷點除錯能看到,在DecodeableRpcResult中是存在隱式引數的。

看下2.6.x的實現
image

image

RpcResultt的attachments通過filter塞到RpcContext中去,這樣我們就能拿到隱式引數了。

而在2.7.x中,Result的attachments沒有被使用到

image

雖然引數傳了過來,但consumer端沒有將它放入RpcContext中,就沒法使用。

為什麼2.7.x不處理呢?

在2.6.x中,dubbo的請求返回物件只有RpcResult

image

而在2.7.x中,RpcResult沒了,新增了AsyncRpcResult和AppResponse,AppResponse是真實的返回資料,它的attachments是存在隱式引數的,但它會被包裝在AsyncRpcResult中,invoke拿到的是AsyncRpcResult,此時從AppResponse中解出資料時丟了attachments。

image

2.7.x中有一個重要的提升是對非同步的支援更加友好,這裡對RpcResult的重構應該就是丟失隱式引數的原因。

dubbo協議如何處理協議的相容的?

RmiProtocol類中能看到dubbo針對2.7.02.6.3兩個邊界進行了版本相容
image

版本資訊從哪裡來呢?從程式碼中看到,從provider的url中獲取引數release(優先)、dubbo來判斷provider的dubbo版本,

dubbo://127.0.0.1:20880/com.newbooo.basic.api.SampleService?anyhost=true&application=ddog-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.newbooo.basic.api.SampleService&methods=getByUid&owner=roshilikang&pid=96150&release=2.7.6&retries=7&side=provider&timestamp=1614235399505

這裡面有些歷史原因,看dubbo 2.6.x的原始碼會發現,在2.6.3版本之前,url中dubbo引數代表的是dubbo的版本,而在2.6.3及以後的版本中,dubbo引數代表的是dubbo協議的版本。

image

  • [2.5.3, 2.6.3)版本中,dubbo版本與dubbo協議沒有分開,都是用url上的dubbo引數,值是對應的版本號,取值範圍是 >=2.0.0 && <=2.6.2
  • [2.6.3, 2.7.0)版本,無法從provider註冊的url上看出dubbo版本,dubbo協議版本是從url的dubbo引數獲取,固定為2.0.2
  • 2.7.0之後的版本,dubbo版本在provider的url release引數上,dubbo協議版本在dubbo引數上,目前還是2.0.2

最後

通過這次分析知道了2.7.x的dubbo為什麼provider不能帶回隱式引數了,這應該是個bug。


搜尋關注微信公眾號"捉蟲大師",後端技術分享,架構設計、效能優化、原始碼閱讀、問題排查、踩坑實踐。

相關文章