解決dubbo問題:forbid consumer(2)


線下環境經常出現類似這種異常:

com.alibaba.dubbo.rpc.RpcException: Forbid consumer 10.0.53.69 access service com.kuaidadi.op.api.pay.service.PayChannelConfigRemoteService from registry 10.0.50.150:2181 use dubbo version 2.5.3, Please check registry access list (whitelist/blacklist).

大致意思是當前調用者被禁止訪問某個服務,請檢查下注冊中心訪問列表,還有黑名單和白名單。

其實線下環境根本沒有對服務做白名單和黑名單機制,因為線下環境給開發人員的賬號是guest,沒有權限做黑白名單。今天有好幾個人問我這個問題,我仔細看了源碼,找出了根源所在。

根據異常棧,拋出這個異常的代碼在RegistryDirectory的第579行,如下:

如果forbidden變量為true,則拋出該異常。forbidden變量默認為false,那么什么時候變成true了呢?看RegistryDirectory的這段代碼:

意思是如果invokerUrls的size為1,並且url的協議頭是Constants.EMPTY_PROTOCOL時,則設置forbidden為false,Constants.EMPTY_PROTOCOL的值是empty。

refreshInvoker方法什么時候被調用呢?當某個服務的provider有變化時就會被調用,例如zookeeper上某個服務的provider目錄里的內容發生變化,則zk監聽器會被觸發,由於provider的數量會發生變化,例如有一個新的provider啟動了,有一個provider下線了,所以必須刷新本地的對provider的連接,具體邏輯就在refreshInvoker方法里,這個方法的調用棧如下:

可以確定的是,zookeeper推送的URL的protocol部分不可能無緣無故變成了empty,肯定是由某個地方更改了,於是看一下Constants.EMPTY_PROTOCOL到底有哪些地方調用了,如下:

見圖中紅色圈圈部分,當zookeeper初次訂閱或者訂閱的信息有變更時,都會觸發toUrlsChanged方法,看看這個方法內部都做了什么,完整代碼如下:

可見如果toUrlsWithoutEmpty的結果是空或者size為0,則強制返回一個protocol為empty的url,看來源頭就在這里了。傳入的List<String> providers實際上就是最新的服務提供者信息,當某個服務沒有任何provider時,providers就變為一個size為o的List了,導致返回一個協議頭為empty的url,進而導致forbidden為true,屏蔽了consumer調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM