溫馨提示×

溫馨提示×

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

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

那些年踩過的Dubbo坑有哪些

發布時間:2021-10-12 10:49:28 來源:億速云 閱讀:186 作者:柒染 欄目:云計算

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

前言

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

dubbo歷史

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

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

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

先交代下背景,我們這邊是從2016年開始使用dubbo,使用的是dubbox-2.8.4 版本,然后因為一些場景不合適改了下代碼,重新打包成2.8.5提交至公司的私服使用。好了,接下來就開始進入正文,聊聊這幾年在dubbo使用過程中遇到坑,以及需要注意的地方吧。

正文

1、超時重試

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

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

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

2、dubbo使用內網ip

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

3、docker里面注冊宿主機內網ip

說到微服務,當然也少不了docker了,我們當前用的是docker+overlay網絡一個結構,直接把dubbo服務丟進容器里面跑的話,注冊進zk的ip是容器ip。所以我們采取了一種折中的方式。

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

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

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

4、未注意服務重名

其實這是我們開發人員粗心大意出現的情況,開發的時候注冊了2個相同簽名的服務,但是業務邏輯是完全不同的,這會導致一個之前運行的正常的業務會偶爾調用失敗,原因是因為dubbo的負載均衡策略,把一部分流量轉移到我們新注冊上來的服務上了,但是處理邏輯不同,導致錯誤。

5、版本的一致性

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

6、屬性配置的優先級

我們在dubbo的過程中會發現,提供者跟消費者中,很多屬性是一樣的,我們該怎么配呢?在dubbo的文檔當中其實有推薦的用法。

在提供者端盡量多提供消費者端的屬性。

參考文檔,原因如下:

  • 作服務的提供方,比服務消費方更清楚服務的性能參數,如調用的超時時間、合理的重試次數等

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

Provider 端盡量多配置 Consumer 端的屬性,讓 Provider 的實現者一開始就思考 Provider 端的服務特點和服務質量等問題。


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

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女