Dubbo 服務 IP 註冊錯誤踩坑經歷
個人部落格地址 studyidea.cn,點選檢視更多原創文章
踩坑
公司最近新建一個機房,需要將現有系統同步部署到新機房,部署完成之後,兩地機房同時對提供服務。系統架構如下圖:
這個系統當前對外採用 Restful
介面,內部遠端採用 Dubbo
,服務註冊中心使用 zookeeper
。服務當前設定只會呼叫本機房內服務。
原先服務都在 A 機房,B 機房為新建機房。B 機房部署完成之後,需要測試 B 機房系統可用性。生產測試的發現 B 機房竟然呼叫 A 機房服務。
A/B 機房網路互相打通,可以互相訪問
通過排查 B 機房服務日誌,發現 Service B
一個服務節點註冊 IP 解析錯誤,將 B 機房機器 IP 解析成 A 機房機器 IP。
於是當測試流量進入 B 機房時,openapi
服務通過註冊中心獲取到錯誤的 Service B
服務地址,從而呼叫了 A 機房的服務。呼叫方式簡化成如下圖。
知識點:Dubbo 服務提供者啟動時將會將服務地址(IP+埠)註冊到註冊中心,消費者啟動時將會通過註冊中心獲取服務提供者地址(IP+埠),後續服務呼叫將會直接通過服務地址直接呼叫。
問題分析
Debug Dubbo
原始碼,定位到 IP
解析程式碼,位於 ServiceConfig#findConfigedHosts
,原始碼如下:
Dubbo 版本為 2.6.7
這個方法原始碼比較長,看起來比較費勁,不過好在這個方法註釋上已經寫明白 IP
Register & bind IP address for service provider, can be configured separately. Configuration priority: environment variables -> java system properties -> host property in config file -> /etc/hosts -> default network address -> first available network address
查詢順序如圖所示:
解析過程,Dubbo
下面將結合圖示講解查詢順序,只要其中一步讀取 IP 符合上述規則,方法就會返回。
第一步將會呼叫 ServiceConfig#getValueFromConfig
從 environment variables
或 java system properties
配置 IP 地址。
這種方式通過在 JVM
啟動引數中顯示指定 IP 。
-DDUBBO_IP_TO_BIND=1.2.3.4
第二步通過讀取 Dubbo
配置檔案配置變數獲取 IP。
<!-- protocol 指定整個 Dubbo 應用服務預設 IP -->
<dubbo:protocol host="1.2.3.4"/>
<!-- provider 指定 Dubbo 應用具體某個服務預設 IP -->
<dubbo:provider host="1.2.3.4"/>
第三步通過呼叫 InetAddress.getLocalHost().getHostAddress()
獲取本地 IP。該方法將會獲取機器 hostname
,然後再在 /etc/hosts
配置檔案中查詢 hostname
對應的配置 IP。
第四步通過 socket
連線註冊中心從而獲取本機 IP。
如果上述幾步都不成功,Dubbo 將會輪詢本機所有網絡卡,直到找到合適的 IP 地址。
問題原因
通過排查上述幾個規則,最後發現本地 /etc/hosts
檔案 IP 配置錯誤, hostname
配置成了 A 機房的 IP 。
總結
Dubbo 在 IP 解析上花費很大功夫,最大程度上幫我們自動獲取正確 IP。但是現實還是很殘酷,真實環境下機器可能存在多網絡卡,內外網 IP,VPN ,或者應用採用 Docker 部署,這些情況下Dubbo
有可能就會獲取到錯誤 IP,從而導致消費者呼叫失敗。如果真遇到這種情況,讀者首先通過上面順序排查 IP 讀取來源,若最後確定 IP 讀取自網絡卡 。這種情況下就只能根據下面幾種方式顯示指定 IP。
配置方式一:
在 JVM
啟動引數中加入如下配置
-DDUBBO_IP_TO_BIND=1.2.3.4
配置方式二:
在 /etc/hosts
設定 hostname
對應的 IP。
配置方式三:
Dubbo
配置檔案顯示指定 IP。
<!-- protocol 指定整個 Dubbo 應用服務預設 IP -->
<dubbo:protocol host="1.2.3.4"/>
<!-- provider 指定 Dubbo 應用具體某個服務預設 IP -->
<dubbo:provider host="1.2.3.4"/>
隨便聊聊
這次的問題其實不大,就是 hosts 檔案配置錯誤,但是整個查詢問題的過程還是值得學習的,深入到了原始碼層面,跟蹤程式碼,最終發現問題。生產出現問題,如何第一時間定位到問題,這是一門學問。我們不僅要了解業務程式碼,也要清楚框架的原理。每一次的踩坑經歷,都是一次考驗,經歷的多了,經驗自然也會多了,這也許就是資深程式設計師與初級程式設計師差別。
幫助連結
https://dubbo.apache.org/zh-cn/blog/dubbo-network-interfaces.html
歡迎關注我的公眾號:程式通事,獲得日常乾貨推送。如果您對我的專題內容感興趣,也可以關注我的部落格:studyidea.cn
相關推薦
Dubbo 服務 IP 註冊錯誤踩坑經歷
個人部落格地址 studyidea.cn,點選檢視更多原創文章 踩坑 公司最近新建一個機房,需要將現有系統同步部署到新機房,部署完成之後,兩地機房同時對提供服務。系統架構如下圖: 這個系統當前對外採用 Restful 介面,內部遠端採用 Dubbo,服務註冊中心使用 zookeeper。服務當前設定只
Uber使用Swift重寫APP的踩坑經歷及解決方案(轉載)
result 框架 退出 帶來 hole 懶漢 將在 例子 穩定 本文出自Uber移動架構和框架組負責人托馬斯·阿特曼於2016年在灣區Swift峰會上的演講,分享了使用Swfit重寫Uber的好與壞。以下為譯文: 我是托馬斯·阿特曼,目前是Uber移動架構和框架組負責人。
Mysql視圖權限設置的踩坑經歷
視圖權限 show view 查看視圖權限 1.事件背景今天臨近中午飯點時,開發同事發來需求,在mariadb庫創建兩個視圖,要求指定帳號有只讀權限。很簡單的需求,連上服務器,兩條grant命令一刷,fulsh privileges 回車,樓主就安心吃飯去了。 2.重點來了,待樓主用餐歸來,(還在
.Net4.6 Task 異步OA現金盤平臺出租函數 比 同步函數 慢5倍 踩坑經歷
數字 沒有 人員 猜想 需要 信道 sleep nlog com 異步Task簡單介紹本標題有點 嘩眾取寵OA現金盤平臺出租QQ2952777280【話仙源碼論壇】hxforum.com【木瓜源碼論壇】papayabbs.com ,各位都別介意(不排除個人技術能力問題) —
Net4.6 Task 異步函數 比 同步函數 慢5倍 踩坑經歷
緩存 each 做事 業務 java 初始 線程 外包 通訊 Net4.6 Task 異步函數 比 同步函數 慢5倍 踩坑經歷 https://www.cnblogs.com/shuxiaolong/p/DotNet_Task_BUG.html 異步Task簡單介紹 本標題
踩坑經歷(一)BigDecimal如何比較大小
案例 BigDecimal a=BigDecimal.valueOf(1.0); BigDecimal b=BigDecimal.valueOf(1.000); 比較大小 if(a.compareTo(b)==0) JDK原始碼 public int
Open-falcon的nodata模組踩坑經歷——agent.alive/pdl=falcon,module=nodata一直為-1的問題
如果你點進來,你可能和我一樣,在看Open-falcon的v0.2版官方教程Nodata模組 按照官方教程,用如下的圖配置一個Nodata專案,這樣agent當機的時候這一項就變成設定好的-1 啟用之後,看一眼Counter中出現了一個新的Counter 喜滋滋地關掉agen
踩坑經歷(八)MySQL 實現 over partition by
建表語句 /* Navicat MySQL Data Transfer Source Server : test Source Server Type : MySQL Source Server Version : 50620 Source Host
踩坑經歷(七)MySQL匯出生產環境表結構和資料
在命令列視窗下執行即可 編號 需求 SQL 1 匯出資料庫為dbname的表結構(其中使用者名稱為root,密碼為dbpasswd,生成的指令碼名為db.sql) my
踩坑經歷(六)MySQL之生成動態SQL語句
delimiter $$ drop procedure if exists test_tb; create procedure test_tb() begin #DECLARE t_error INTEGER DEFAULT 0; -- DECLARE u
踩坑經歷(五)一次關於MySQL儲存過程的排錯
SQL語句 -- #開啟定時器,預設為關閉狀態 set global event_scheduler =1; #或者set GLOBAL event_scheduler = ON; use monitorsys; drop event if exists report_back
踩坑經歷(四)建立索引儲存過程
需求:存在刪除索引並且建立索引 儲存過程 DROP PROCEDURE IF EXISTS add_Index; delimiter // CREATE PROCEDURE add_Index ( IN p_dbname VARCHAR (200), I
踩坑經歷(九)一條雙層迴圈的SQL實現業務需求
業務場景 類目 背景 資料特點 表沒有唯一主鍵,相同id可能有很多條 需求 取每條資料記錄的最新記錄 SQL實現 (1
Mysql踩坑經歷
今天下午收到同事反饋資料歸檔有一個任務失敗了,並且給我截圖錯誤資訊是BadSqlGrammarException,這個錯誤相信大家應該都見過,顯然是SQL語句裡面存在語法錯誤;但是,我的SQL怎麼會有問題呢!!我這麼穩的人…更何況其他歸檔任務都是用的這個S
Spring Boot 和 Spring Cloud Feign呼叫服務及傳遞引數踩坑記錄
背景 在Spring Cloud Netflix棧中,各個微服務都是以HTTP介面的形式暴露自身服務的,因此在呼叫遠端服務時就必須使用HTTP客戶端。我們可以使用JDK原生的URLConnection、Apache的
記一次使用Jackson對Java物件序列化和反序列化的踩坑經歷
背景大概是這樣,專案中的兩個服務A和B依賴了同一個common包的Java類,A對該類json序列化,而B對其反序列化。在一次common包升級過程中,這個Java類中增加了一個屬性,由於B其實用不到這個屬性,就只把A給升級打包了,這就導致B在反序列化時出現了一個異常:com.fasterxml.j
Dubbo服務只註冊
如果有兩個映象環境,連個註冊中心,有一個服務只在其中一個註冊中心有部署,另一個註冊中心還沒來得及部署,而兩個註冊中心的其他應用都需要依賴此服務,所以,需要將服務同時註冊到兩個註冊中心,但卻不能讓此服務同時依賴兩個註冊中心的其他服務。 可以讓服務提供者,只註冊服務到另一註
踩坑經歷三(三)SQL特殊排序處理
需求:2排最前面,null排最後 問題解決:IFNULL()函式 和 FIND_IN_SET()函式 select id, organization_name, organization_code,
Spring security oauth2 "no bean resolver registered" 錯誤踩坑
Spring security oauth2 “no bean resolver registered” 錯誤踩坑 錯誤堆疊資訊: java.lang.IllegalArgumentException: Failed to evaluate expressio
Bootstrap踩坑經歷
Bootstrap是一款十分受歡迎的前端響應式框架,裡面幾乎包含了所有你能想到的優秀元件,設計出來的網站十分炫酷,但是使用過程並沒有想象中的那麼順利,這裡釋出一下使用Bootstrap時所可能遇到的'