Dubbo 服务 IP 注册错误踩坑经历

Stella981
• 阅读 754

个人博客地址 studyidea.cn,点击查看更多原创文章

踩坑

公司最近新建一个机房,需要将现有系统同步部署到新机房,部署完成之后,两地机房同时对提供服务。系统架构如下图:

Dubbo 服务 IP 注册错误踩坑经历

这个系统当前对外采用 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 注册错误踩坑经历

知识点:Dubbo 服务提供者启动时将会将服务地址(IP+端口)注册到注册中心,消费者启动时将会通过注册中心获取服务提供者地址(IP+端口),后续服务调用将会直接通过服务地址直接调用。

问题分析

Debug Dubbo 源码,定位到 IP 解析代码,位于 ServiceConfig#findConfigedHosts,源码如下:

Dubbo 版本为 2.6.7

Dubbo 服务 IP 注册错误踩坑经历

这个方法源码比较长,看起来比较费劲,不过好在这个方法注释上已经写明白 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 注册错误踩坑经历

解析过程,Dubbo 将会过滤无用 IP,过滤规则如下:

Dubbo 服务 IP 注册错误踩坑经历

下面将结合图示讲解查找顺序,只要其中一步读取 IP 符合上述规则,方法就会返回。

第一步将会调用 ServiceConfig#getValueFromConfigenvironment variablesjava system properties 配置 IP 地址。Dubbo 服务 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。

Dubbo 服务 IP 注册错误踩坑经历

第四步通过 socket 连接注册中心从而获取本机 IP。

如果上述几步都不成功,Dubbo 将会轮询本机所有网卡,直到找到合适的 IP 地址。

Dubbo 服务 IP 注册错误踩坑经历

问题原因

通过排查上述几个规则,最后发现本地 /etc/hosts 文件 IP 配置错误, hostname 配置成了 A 机房的 IP

总结

Dubbo 在 IP 解析上花费很大功夫,最大程度上帮我们自动获取正确 IP。但是现实还是很残酷,真实环境下机器可能存在多网卡,内外网 IPVPN ,或者应用采用 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 注册错误踩坑经历

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
国庆假期玩不停双重好礼放肆领
自2021年10月1日00:00起至2021年10月7日24:00,新注册并激活(需全部完成账号注册的五个步骤,否则账号状态并未激活)AWS海外区域账户,填写页面下方表单,即可申领价值$200美元的AWS海外区域账户服务抵扣券直充到您的账户,用以抵扣服务消费,助您轻松体验多个云迁移应用场景。同时,您还可获赠AWS精美祥云纪念T恤一件。,仅限7天AW
AWS国庆双重礼,仅限7天
自2021年10月1日00:00起至2021年10月7日24:00,新注册并激活(需全部完成账号注册的五个步骤,否则账号状态并未激活)AWS海外区域账户,填写页面下方表单,即可申领价值$200美元的AWS海外区域账户服务抵扣券直充到您的账户,用以抵扣服务消费,助您轻松体验多个云迁移应用场景。同时,您还可获赠AWS精美祥云纪念T恤一件。,仅限7天$20
AWS国庆双重礼,仅限7天
自2021年10月1日00:00起至2021年10月7日24:00,新注册并激活(需全部完成账号注册的五个步骤,否则账号状态并未激活)AWS海外区域账户,填写页面下方表单,即可申领价值$200美元的AWS海外区域账户服务抵扣券直充到您的账户,用以抵扣服务消费,助您轻松体验多个云迁移应用场景。同时,您还可获赠AWS精美祥云纪念T恤一件。,仅限7天$20
Stella981 Stella981
3年前
Golang注册Eureka的工具包goeureka发布
1.简介提供Go微服务客户端注册到Eureka中心。点击:github地址(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2FSimonWang00%2Fgoeureka),欢迎各位多多star!(已通过测试验证,用于正式生产部署)2.原理
AWS国庆双重礼,仅限7天
自2021年10月1日00:00起至2021年10月7日24:00,新注册并激活(需全部完成账号注册的五个步骤,否则账号状态并未激活)AWS海外区域账户,填写页面下方表单,即可申领价值$200美元的AWS海外区域账户服务抵扣券直充到您的账户,用以抵扣服务消费,助您轻松体验多个云迁移应用场景。同时,您还可获赠。国庆双重礼,仅限7天$200美元AWS服务抵
Stella981 Stella981
3年前
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法参考文章:(1)Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.codeprj.com%2Fblo
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这