1. 程式人生 > >Dubbo 服務 IP 註冊錯誤踩坑經歷

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,過濾規則如下:

下面將結合圖示講解查詢順序,只要其中一步讀取 IP 符合上述規則,方法就會返回。

第一步將會呼叫 ServiceConfig#getValueFromConfigenvironment variablesjava 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時所可能遇到的'