從dubbo源碼分析qos-server端口沖突問題及解決
在這分布式系統(tǒng)架構(gòu)盛行的時(shí)代,很多互聯(lián)網(wǎng)大佬公司開源出自己的分布式RPC系統(tǒng)框架,例如:阿里的dubbo,谷歌的gRPC,apache的Thrift。
而在我們公司一直都在推薦使用dubbo,今天就來講講在使用dubbo過程出現(xiàn)的qos-server端口沖突問題。
什么是dubbo的qos-server呢?
qos是dubbo的在線運(yùn)維命令,dubbo2.5.8新版本重構(gòu)了telnet模塊,提供了新的telnet命令支持,新版本的telnet端口與dubbo協(xié)議的端口是不同的端口,默認(rèn)為22222,可以通過配置文件dubbo.properties修改。
在dubbo2.5.7版本之前是不支持注解配置的,因此公司框架對(duì)dubbo做了二次封裝,通過自定義注解@EnableDuubo來支持dubbo的注解配置,并簡(jiǎn)化了server provider,server consumer,server registry配置,開發(fā)人員只要在spring boot啟動(dòng)類中添加@EnableDuubo即可開始自己的業(yè)務(wù)代碼開發(fā),節(jié)省大量的時(shí)間。
最近在項(xiàng)目開發(fā)過程中由于需要調(diào)試,在本地同一臺(tái)機(jī)器上開了兩個(gè)運(yùn)行實(shí)例,一個(gè)是dubbo provider實(shí)例,一個(gè)是dubbo consumer實(shí)例。
首先啟動(dòng)provider實(shí)例沒有任務(wù)問題,當(dāng)啟動(dòng)consumer以后,控制臺(tái)卻拋出如下問題,
為了解決端口沖突,開始在項(xiàng)目中使用各種idea搜索快捷鍵搜索關(guān)鍵字qos-server和22222都沒有搜索到任何信息。
一般日志都會(huì)打印包名和類型,便于快速定位問題,然后這里日志打印根本沒有輸出包名和類,趕緊修改日志打印格式配置,終于得到如下錯(cuò)誤信息
原來是這個(gè)錯(cuò)誤是dubbo的com.alibaba.dubbo.qos.server的Server類中打印出來,查看Server類源碼發(fā)現(xiàn)在方法start中調(diào)用了netty的初始化方法,并將port作為被外部訪問的qos-server端口,代碼如下
問題來了
問題1
什么時(shí)候會(huì)啟用qos服務(wù)呢,端口是何時(shí)被賦值的呢?
在Server類中可以看到唯一為 port參數(shù)賦值的方法只有setPor()方法,查看發(fā)現(xiàn)也只有在QosProtocolWrapper中調(diào)用了setPort()方法,查看源碼可以發(fā)現(xiàn),在該類的startQosServer()方法中會(huì)首先從url中解析qos.enable參數(shù),如果未獲取到該參數(shù)值,則默認(rèn)啟動(dòng)qos服務(wù),同時(shí)服務(wù)端口也是從url中解析,默認(rèn)使用22222。
問題2
那么這個(gè)url到底是啥呢?
其實(shí)斷點(diǎn)程序可以發(fā)現(xiàn),該url就是項(xiàng)目中對(duì)dubbo的一些配置信息,例如注冊(cè)中心地址,超時(shí)時(shí)間,超時(shí)重試次數(shù)等等,由于項(xiàng)目中沒有對(duì)qos服務(wù)的配置,因此全部采用了默認(rèn)配置,導(dǎo)致端口沖突。
問題3
如何禁用qos服務(wù)呢?
雖然qos端口沖突并影響服務(wù)消費(fèi)者消費(fèi)服務(wù),但是每次程序啟動(dòng)總是拋出端口沖突異常,有強(qiáng)迫證的程序肯定以為程序哪里出錯(cuò)了,總會(huì)有那么一點(diǎn)忐忑。
而且大多數(shù)情況可能并不需要這個(gè)qos服務(wù),默認(rèn)開啟浪費(fèi)端口,浪費(fèi)機(jī)器資源(雖然資源占用并不一定很多),如果你是 java 注解配置,可以通過如下代碼禁用qos服務(wù),有些版本可能沒有提供該API,如下是dubbo 2.6.2中的API
或者通過dubbo官網(wǎng)已經(jīng)給出了文檔來配置
dubbo2.6.8 的配置項(xiàng) dubbo.application.qos-port=2222 dubbo.application.qos-enable=true dubbo.application.qos-accept-foreign-ip=false
問題4
為什么我獨(dú)立搭建dubbo分布式服務(wù)的時(shí)候沒有出現(xiàn)qos-server端口沖突呢?
原因在于qos-server 需要netty4版本的支持,默認(rèn)情況下dubbo不會(huì)引用netty4的依賴包,(而項(xiàng)目中有依賴netty4,因此拋出端口異常,)因此在QosProtocolWrapper類中調(diào)用Server類的start()方法啟動(dòng)qos服務(wù)時(shí),會(huì)拋出ClassNotFoundException,QosProtocolWrapper的startQosServer()方法僅僅try catch了異常,未做任何處理,因此根本沒有拋出任何異常,這是極其反對(duì)的一種做法,至少打個(gè)日志啊。
源碼如下:
總結(jié)
1.開發(fā)過程中日志打印及日志打印格式是非常重要的,可能大大減少問題定位的時(shí)間,因此一定要注意有效的日志輸出
2.要學(xué)會(huì)解決問題的思路,端口沖突是一個(gè)很常見的問題,通過百度或者谷歌搜索可能幾分鐘就能解決,只是想借此來更多的了解框架的實(shí)現(xiàn)細(xì)節(jié),知其然知其所以然。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java如何將若干時(shí)間區(qū)間進(jìn)行合并的方法步驟
這篇文章主要介紹了Java如何將若干時(shí)間區(qū)間進(jìn)行合并的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02springboot對(duì)數(shù)據(jù)庫(kù)密碼加密的實(shí)現(xiàn)
這篇文章主要介紹了springboot對(duì)數(shù)據(jù)庫(kù)密碼加密的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12mybatis報(bào)錯(cuò)元素內(nèi)容必須由格式正確的字符數(shù)據(jù)或標(biāo)記組成異常的解決辦法
今天小編就為大家分享一篇關(guān)于mybatis查詢出錯(cuò)解決辦法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12java如何實(shí)現(xiàn)基于opencv全景圖合成實(shí)例代碼
全景圖相信大家應(yīng)該都不陌生,下面這篇文章主要給大家介紹了關(guān)于java如何實(shí)現(xiàn)基于opencv全景圖合成的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07java實(shí)現(xiàn)上傳文件到服務(wù)器和客戶端
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)上傳文件到服務(wù)器和客戶端,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01Java實(shí)現(xiàn)BP神經(jīng)網(wǎng)絡(luò)MNIST手寫數(shù)字識(shí)別的示例詳解
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)BP神經(jīng)網(wǎng)絡(luò)MNIST手寫數(shù)字識(shí)別的相關(guān)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-01-01Java中main函數(shù)的String[]?args用法舉例詳解
這篇文章主要給大家介紹了關(guān)于Java中main函數(shù)的String[]?args用法的相關(guān)資料,JAVA類中main函數(shù)的參數(shù)String[]?args指的是運(yùn)行時(shí)給main函數(shù)傳遞的參數(shù),文中通過圖文以及代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12Java高性能新一代構(gòu)建工具M(jìn)aven-mvnd(實(shí)踐可行版)
這篇文章主要介紹了Java高性能新一代構(gòu)建工具M(jìn)aven-mvnd(實(shí)踐可行版),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06javaweb前端向后端傳值的幾種方式總結(jié)(附代碼)
javaweb是java開發(fā)中的一個(gè)方向,下面這篇文章主要給大家介紹了關(guān)于javaweb前端向后端傳值的幾種方式的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03