溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

那些年踩過的Dubbo坑有哪些

發(fā)布時(shí)間:2021-10-12 10:49:28 來源:億速云 閱讀:144 作者:柒染 欄目:云計(jì)算

那些年踩過的Dubbo坑有哪些,針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

前言

微服務(wù)架構(gòu)在如今的9102年已經(jīng)不是什么新鮮的話題了,但是怎么做好微服務(wù)架構(gòu),卻又是一個(gè)永恒的話題。比如服務(wù)粒度的劃分,怎么控制好粗細(xì)?服務(wù)劃分后,對于項(xiàng)目的部署會有什么改變?...  這會是一個(gè)很大的話題,以后可以分開篇章探討一翻,但是我們本篇并不打算聊這個(gè),而是討論一下具體的實(shí)現(xiàn)技術(shù)--dubbo。

dubbo歷史

2011 年末,阿里巴巴在 GitHub 上開源了基于 Java 的分布式服務(wù)治理框架 Dubbo,之后它成為了國內(nèi)該類開源項(xiàng)目的佼佼者,許多開發(fā)者對其表示青睞。同時(shí),先后有不少公司在實(shí)踐中基于 Dubbo 進(jìn)行分布式系統(tǒng)架構(gòu),目前在 GitHub 上,它的 fork、star 數(shù)均已破萬。2014 年 10 月 30 號發(fā)布版本 dubbo-2.4.11,修復(fù)了一個(gè)小 Bug,版本又陷入漫長的停滯到2017年九月份。

在dubbo停滯的期間呢,當(dāng)當(dāng)網(wǎng) Fork 了阿里的一個(gè) Dubbo 版本開始維護(hù),并命名為 dubbox-2.8.0。值得注意的是,當(dāng)當(dāng)網(wǎng)擴(kuò)展 Dubbo 服務(wù)框架支持 REST 風(fēng)格遠(yuǎn)程調(diào)用,并且跟隨著 ZooKeepe 和 Spring 升級了對應(yīng)的版本。之后 Dubbox 一直在小版本維護(hù),2015 年 3 月 31 號發(fā)布了最后一個(gè)版本 dubbox-2.8.4。筆者公司用的也是這個(gè)版本,并稍微改造了下源碼,下面會有提及。

其實(shí)在當(dāng)前說到微服務(wù),可能大家第一反應(yīng)是springcloud,spring全家桶帶來的便捷是顯而易見的,然而為什么我們這里聊的是dubbo呢?原因之一是因?yàn)楣P者公司只用了dubbo(別扔雞蛋....),其二呢其實(shí)rpc框架很多原理是相通的,當(dāng)我們理解了其中一個(gè),再去看其他的框架,會有一種似曾相識的感覺,最后也沒必要去爭論XX框架的好與壞,選擇最適合自己業(yè)務(wù)的就是最好的。

先交代下背景,我們這邊是從2016年開始使用dubbo,使用的是dubbox-2.8.4 版本,然后因?yàn)橐恍﹫鼍安缓线m改了下代碼,重新打包成2.8.5提交至公司的私服使用。好了,接下來就開始進(jìn)入正文,聊聊這幾年在dubbo使用過程中遇到坑,以及需要注意的地方吧。

正文

1、超時(shí)重試

這是一個(gè)很經(jīng)典的坑,當(dāng)時(shí)由于剛使用dubbo,很多配置都是基于默認(rèn)的。剛好此時(shí)在項(xiàng)目中,有一個(gè)機(jī)器人送禮的邏輯比較復(fù)雜,當(dāng)遇到某些特定的條件時(shí),該邏輯的耗時(shí)會比正常情況下變長,這時(shí)候就出現(xiàn)了一個(gè)很神奇的現(xiàn)象,為何我只觸發(fā)了一次送禮的請求,而線上卻送了三次?

剛遇到這種情況可我驚呆了,重新審視了代碼,發(fā)現(xiàn)并無問題。這就奇怪了,哪里來的3次?后來掉了幾根頭發(fā)以后,才在dubbo的文檔中發(fā)現(xiàn)了服務(wù)這塊有timeout跟retry屬性,默認(rèn)timeout=1000ms,retry=2。這下就豁然開朗,原來是第一次調(diào)用超時(shí),導(dǎo)致又重試了2次,一共就是3次了。

找到問題的原因,我們就有辦法解決了。由于我們這個(gè)接口不是冪等性的,而且也不用返回什么信息給調(diào)用者,所以我們可以通過一個(gè)線程池來執(zhí)行這段耗時(shí)的邏輯,讓rpc調(diào)用可以比較快的返回給調(diào)用者。這樣就不存在超時(shí)的問題了?;蛘呖梢耘浜显黾觮imeout時(shí)間跟retry=0也能實(shí)現(xiàn),具體的業(yè)務(wù)邏輯需要自己找到合適的解決方案。

2、dubbo使用內(nèi)網(wǎng)ip

正常情況下,我們的服務(wù)調(diào)用推薦走內(nèi)網(wǎng)連接的方式,效率是比較高的。但是有些特殊的情況,我們需要dubbo注冊服務(wù)的時(shí)候使用外網(wǎng)ip,該怎么修改呢?這時(shí)候就需要修改我們的服務(wù)器上 /etc/hosts 文件了,新增一條 “外網(wǎng)ip  主機(jī)名”的記錄,restart我們的服務(wù)即可。

3、docker里面注冊宿主機(jī)內(nèi)網(wǎng)ip

說到微服務(wù),當(dāng)然也少不了docker了,我們當(dāng)前用的是docker+overlay網(wǎng)絡(luò)一個(gè)結(jié)構(gòu),直接把dubbo服務(wù)丟進(jìn)容器里面跑的話,注冊進(jìn)zk的ip是容器ip。所以我們采取了一種折中的方式。

利用docker的特性,我們在創(chuàng)建容器的時(shí)候,把宿主機(jī)的ip以及需要暴露的端口寫進(jìn)容器的環(huán)境變量里面。然后就是修改dubbox的源碼了,源碼的com.alibaba.dubbo.registry.integration.RegistryProtocol類的getRegistedProviderUrl

方法,此方法用于返回注冊到注冊中心的URL。

private URL getRegistedProviderUrl(final Invoker<?> originInvoker){
        //targetUrl 注冊中心看到的地址
        URL targetUrl;
        URL providerUrl = getProviderUrl(originInvoker);
        //配置的容器環(huán)境變量
        String envParameterHost=System.getenv(ENV_HOST_KEY);
        String envParameterPort=System.getenv(ENV_PORT_KEY);
        if (StringUtils.isBlank(envParameterHost)||StringUtils.isBlank(envParameterPort)){//非容器環(huán)境:執(zhí)行原來的注冊邏輯
            targetUrl=providerUrl.removeParameters(getFilteredKeys(providerUrl)).removeParameter(Constants.MONITOR_KEY);
        }else {//容器環(huán)境,如果環(huán)境變量中DOCKER_NAT_HOST和DOCKER_NAT_PORT兩個(gè)值都不為空則直接將這兩個(gè)值作為url注冊到zk
            //執(zhí)行重新拼接url的操作,涉及敏感代碼這里不展示了
            targetUrl=dockerRegUrlWithHostAndPort;
        }
        return targetUrl;
    }

4、未注意服務(wù)重名

其實(shí)這是我們開發(fā)人員粗心大意出現(xiàn)的情況,開發(fā)的時(shí)候注冊了2個(gè)相同簽名的服務(wù),但是業(yè)務(wù)邏輯是完全不同的,這會導(dǎo)致一個(gè)之前運(yùn)行的正常的業(yè)務(wù)會偶爾調(diào)用失敗,原因是因?yàn)閐ubbo的負(fù)載均衡策略,把一部分流量轉(zhuǎn)移到我們新注冊上來的服務(wù)上了,但是處理邏輯不同,導(dǎo)致錯(cuò)誤。

5、版本的一致性

dubbo當(dāng)前的releases版本已經(jīng)去到2.7.1了,項(xiàng)目中要注意一下不同項(xiàng)目間版本的一致性,或者是dubbo跟dubbox的一些差別,最好做到統(tǒng)一,不然出現(xiàn)問題解決的成本會比較高。

6、屬性配置的優(yōu)先級

我們在dubbo的過程中會發(fā)現(xiàn),提供者跟消費(fèi)者中,很多屬性是一樣的,我們該怎么配呢?在dubbo的文檔當(dāng)中其實(shí)有推薦的用法。

在提供者端盡量多提供消費(fèi)者端的屬性。

參考文檔,原因如下:

  • 作服務(wù)的提供方,比服務(wù)消費(fèi)方更清楚服務(wù)的性能參數(shù),如調(diào)用的超時(shí)時(shí)間、合理的重試次數(shù)等

  • 在 Provider 端配置后,Consumer 端不配置則會使用 Provider 端的配置,即 Provider 端的配置可以作為 Consumer 的缺省值 。否則,Consumer 會使用 Consumer 端的全局設(shè)置,這對于 Provider 是不可控的,并且往往是不合理的

Provider 端盡量多配置 Consumer 端的屬性,讓 Provider 的實(shí)現(xiàn)者一開始就思考 Provider 端的服務(wù)特點(diǎn)和服務(wù)質(zhì)量等問題。


其實(shí)在dubbo的使用過程中,還有挺多問題這里沒列出來的,但是解決方法都差不多,首先文檔要熟,做到心中有數(shù),比如dubbo功能的成熟度,有些是不推薦在線上使用的,這時(shí)你就要謹(jǐn)慎了。然后文檔里面確實(shí)是有遺漏的問題,我們有必要可以debug dubbo的源碼,這個(gè)過程會比較痛苦,但是對于排查問題跟個(gè)人能力的提高是有很有幫助的。

關(guān)于那些年踩過的Dubbo坑有哪些問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI