微服務架構在現在的9102年已經不是什麼新鮮的話題了,可是怎麼作好微服務架構,卻又是一個永恆的話題。好比服務粒度的劃分,怎麼控制好粗細?服務劃分後,對於項目的部署會有什麼改變?… 這會是一個很大的話題,之後能夠分開篇章探討一翻,可是咱們本篇並不打算聊這個,而是討論一下具體的實現技術–dubbo。程序員
2011 年底,阿里巴巴在 GitHub 上開源了基於 Java 的分佈式服務治理框架 Dubbo,以後它成爲了國內該類開源項目的佼佼者,許多開發者對其表示青睞。同時,前後有很多公司在實踐中基於 Dubbo 進行分佈式系統架構,目前在 GitHub 上,它的 fork、star 數均已破萬。2014 年 10 月 30 號發佈版本 dubbo-2.4.11,修復了一個小 Bug,版本又陷入漫長的停滯到2017年九月份。web
在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框架的好與壞,選擇最適合本身業務的就是最好的。spring
先交代下背景,咱們這邊是從2016年開始使用dubbo,使用的是dubbox-2.8.4 版本,而後由於一些場景不合適改了下代碼,從新打包成2.8.5提交至公司的私服使用。好了,接下來就開始進入正文,聊聊這幾年在dubbo使用過程當中遇到坑,以及須要注意的地方吧。docker
一、超時重試服務器
這是一個很經典的坑,當時因爲剛使用dubbo,不少配置都是基於默認的。恰好此時在項目中,有一個機器人送禮的邏輯比較複雜,當遇到某些特定的條件時,該邏輯的耗時會比正常狀況下變長,這時候就出現了一個很神奇的現象,爲什麼我只觸發了一次送禮的請求,而線上卻送了三次?網絡
剛遇到這種狀況可我驚呆了,從新審視了代碼,發現並沒有問題。這就奇怪了,哪裏來的3次?後來掉了幾根頭髮之後,纔在dubbo的文檔中發現了服務這塊有timeout跟retry屬性,默認timeout=1000ms,retry=2。這下就豁然開朗,原來是第一次調用超時,致使又重試了2次,一共就是3次了。架構
找到問題的緣由,咱們就有辦法解決了。因爲咱們這個接口不是冪等性的,並且也不用返回什麼信息給調用者,因此咱們能夠經過一個線程池來執行這段耗時的邏輯,讓rpc調用能夠比較快的返回給調用者。這樣就不存在超時的問題了。或者能夠配合增長timeout時間跟retry=0也能實現,具體的業務邏輯須要本身找到合適的解決方案。併發
二、dubbo使用內網ip負載均衡
正常狀況下,咱們的服務調用推薦走內網鏈接的方式,效率是比較高的。可是有些特殊的狀況,咱們須要dubbo註冊服務的時候使用外網ip,該怎麼修改呢?這時候就須要修改咱們的服務器上 /etc/hosts 文件了,新增一條 「外網ip 主機名」的記錄,restart咱們的服務便可。
三、docker裏面註冊宿主機內網ip
說到微服務,固然也少不了docker了,咱們當前用的是docker+overlay網絡一個結構,直接把dubbo服務丟進容器裏面跑的話,註冊進zk的ip是容器ip。因此咱們採起了一種折中的方式。
利用docker的特性,咱們在建立容器的時候,把宿主機的ip以及須要暴露的端口寫進容器的環境變量裏面。而後就是修改dubbox的源碼了,源碼的com.alibaba.dubbo.registry.integration.RegistryProtocol類的getRegistedProviderUrl
方法,此方法用於返回註冊到註冊中心的URL。
<pre style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">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; } </pre>
四、未注意服務重名
其實這是咱們開發人員粗枝大葉出現的狀況,開發的時候註冊了2個相同簽名的服務,可是業務邏輯是徹底不一樣的,這會致使一個以前運行的正常的業務會偶爾調用失敗,緣由是由於dubbo的負載均衡策略,把一部分流量轉移到咱們新註冊上來的服務上了,可是處理邏輯不一樣,致使錯誤。
五、版本的一致性
dubbo當前的releases版本已經去到2.7.1了,項目中要注意一下不一樣項目間版本的一致性,或者是dubbo跟dubbox的一些差異,最好作到統一,否則出現問題解決的成本會比較高。
六、屬性配置的優先級
咱們在dubbo的過程當中會發現,提供者跟消費者中,不少屬性是同樣的,咱們該怎麼配呢?在dubbo的文檔當中其實有推薦的用法。
在提供者端儘可能多提供消費者端的屬性。
參考文檔,緣由以下:
做服務的提供方,比服務消費方更清楚服務的性能參數,如調用的超時時間、合理的重試次數等
在 Provider 端配置後,Consumer 端不配置則會使用 Provider 端的配置,即 Provider 端的配置能夠做爲Consumer 的缺省值 。不然,Consumer 會使用 Consumer 端的全局設置,這對於 Provider是不可控的,而且每每是不合理的
Provider 端儘可能多配置 Consumer 端的屬性,讓 Provider 的實現者一開始就思考 Provider 端的服務特色和服務質量等問題。
其實在dubbo的使用過程當中,還有挺多問題這裏沒列出來的,可是解決方法都差很少,首先文檔要熟,作到心中有數,好比dubbo功能的成熟度,有些是不推薦在線上使用的,這時你就要謹慎了。而後文檔裏面確實是有遺漏的問題,咱們有必要能夠debug dubbo的源碼,這個過程會比較痛苦,可是對於排查問題跟我的能力的提升是有頗有幫助的。
針對於上面所涉及到的知識點我總結出了有1到5年開發經驗的程序員在面試中涉及到的絕大部分架構面試題及答案作成了文檔和架構視頻資料免費分享給你們(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分佈式、高併發等架構技術資料),但願能幫助到您面試前的複習且找到一個好的工做,也節省你們在網上搜索資料的時間來學習,也能夠關注我一下之後會有更多幹貨分享。