个人博客地址 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。但是现实还是很残酷,真实环境下机器可能存在多网卡,内外网 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 注册错误踩坑经历相关推荐

  1. 一次关于 Dubbo 服务 IP 注册错误的踩坑经历

    大家好,我是鸭血粉丝,一位经常踩坑的程序员.今天我给大家说一下我踩的 Dubbo 的坑.所谓 bug 如风,常伴吾身,hasaki ~ 这不最近又遇到个问题,Dubbo 服务 IP 注册错误,好了,下 ...

  2. springCloud项目不能向EurekaServer 注册多个EurekaClient时(端口不一致)方法及踩坑经历

    spring cloud 问题说明:springCloud项目不能向EurekaServer 注册多个EurekaClient时(端口不一致)方法及踩坑经历: 前提--->已经能够通过Eurek ...

  3. 记一次成功把Vue2后台项目改造成Vite2的踩坑经历

    文章目录 前言 一.项目背景 1.1.为什么要选择Vite 二.迁移前的准备 2.1.补全.vue后缀 2.2.移动public/index.html的位置 2.2.1.通过vite-plugin-h ...

  4. 一次kvm嵌套虚拟化踩坑经历

    女主宣言 嵌套虚拟化就是虚拟化环境里再次进行虚拟化,简单的说就是虚拟机里运行虚拟机,听起来有点递归的感觉.那是不是可以无限嵌套下去呢?递归有终结条件,否则无限递归下去资源耗尽,嵌套虚拟化嵌套层次越深复 ...

  5. 【golang程序包推荐分享】分享亿点点golang json操作及myJsonMarshal程序包开发的踩坑经历 :)

    目录[阅读时间:约5分钟] 一.概述 1.Json的作用 2.Go官方 encoding/json 包 3. golang json的主要操作 二.Json Marshal:将数据编码成json字符串 ...

  6. GPCC安装以及踩坑经历

    gpcc安装以及踩坑经历 官方下载地址文档 https://network.pivotal.io/products/pivotal-gpdb#/releases/29190 安装开始之前 chown ...

  7. yolov5-4.0环境搭建,零基础小白都能看得懂的教程。YOLOv5搭建的最快搭建方式,踩坑经历详谈)yolov5/yolov4/yolov3/yolov3通>>>>>>>>>>>>>>>>>第一章

    第一章:python最新YOLOv5-4.0环境搭建,零基础小白都能看得懂的教程.YOLOv5搭建的最快搭建方式,踩坑经历详谈 环境准备: yolov5-4.0环境搭建整体说明 2,anaconda的 ...

  8. 微信公众号 卡券 addCard 签名错误 踩坑记录

    微信公众号 卡券 addCard 签名错误 踩坑记录 今天做微信卡券 添加卡券一直报签名错误 参考了好多文档 理了下思路 希望对遇到这问题的人有帮助.另外 本人小白一名,代码有不规范的地方,请大神勿喷 ...

  9. uniapp 引入阿里矢量图标库的详细步骤及踩坑经历

    uniapp 引入阿里矢量图标库的详细步骤及踩坑经历 首先在阿里矢量图标库选择自己喜欢的图标 加购物车如下图 点击右上角的购物车 添加到项目 这里有坑 首先你不选中在线链接 你是看不到 @font-f ...

  10. Dubbo服务的注册与发现

    Dubbo服务的注册与发现 前言 最近参与的项目是一个基于Dubbo的项目,在开发过程中有些同事对于Dubbo服务的注册与发现机制,似乎不太了解.所以我抽空和他简单聊了聊我对Dubbo机制的了解. 正 ...

最新文章

  1. shell特殊符号cut命令,sort_wc_uniq命令,tee_tr_split命令
  2. STL常用的拷贝和替换算法
  3. numpy求解矩阵的特征值和特征向量
  4. 选好财务软件做好企业管理
  5. ubuntu 安装 wifi 驱动_论如何在 MacBook Pro 安装 Ubuntu 18.04(解决 wifi、触摸板、键盘驱动)...
  6. git pull ---rebase
  7. Android UI学习之TextView
  8. pillow python histogram_Python中的PIL库
  9. 开源内网DNS服务器软件介绍
  10. 2022全球C++及系统软件技术大会将于9月上海隆重召开,豪华嘉宾阵容揭晓
  11. ar ebs 销售订单关闭_ZARA母公司拟关闭1200家门店,拿什么拯救快时尚品牌?
  12. 接口监控,系统监控,服务保证
  13. protobuf 与 redis 的结合
  14. 想不想修真鸿蒙之礼奖励,想不想修真论道之礼额外奖励获取攻略
  15. 继承-super详解
  16. FTP使用教程之Filezilla使用教程
  17. godaddy新建二级域名
  18. window的dos命令学习笔记 七
  19. 数据驱动:大众点评精准化营销实践
  20. 打印机安全研究(二):打印机攻击测试方法和利用工具

热门文章

  1. Linux-SHELL基本操作
  2. POJ 2406 Power Strings
  3. 拓端tecdat|【数据分享】学生受欢迎程度评价数据集
  4. 拓端tecdat|R语言中使用RCPP并行计算指数加权波动率
  5. 拓端tecdat|R语言中的风险价值模型度量指标TVaR与VaR
  6. Linux复习-C程序编译工具
  7. someip协议_汽车以太网SOMEIP协议课件抢先看
  8. 把collections.Counter的计数结果转为pandas的DataFrame
  9. DeepFake技术--fakeapp, faceswap, deepfacelab等deepfakes换脸程序的简单对比
  10. SQLServer数据库中截取字符串的常用方法