大家好,我是鸭血粉丝,一位经常踩坑的程序员。今天我给大家说一下我踩的 Dubbo 的坑。所谓 bug 如风,常伴吾身,hasaki ~

这不最近又遇到个问题,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+端口)注册到注册中心,消费者启动时将会通过注册中心获取服务提供者地址(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

总结

这次的问题其实不大,就是 hosts 文件配置错误,但是整个查找问题的过程还是值得学习的,深入到了源码层面,跟踪代码,最终发现问题。毕竟运维人员和开发人员在一定的程度上还是会出现沟通问题,而且还是生产环境,所以更加需要仔细。

我们可以看到 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"/>

帮助链接

https://dubbo.apache.org/zh-cn/blog/dubbo-network-interfaces.html

1. 全栈架构之打包推荐【建议收藏,常读】

2. 探讨确保消息消费幂等性的几种方式

3. 分布式系统中Session共享的常用方案

4. Java语言“坑爹”排行榜TOP 10

5. 我是一个Java类(附带精彩吐槽)

6. mysql索引失效,差点我的工作凉了

7. 既生synchronized,何生volatile?

8. 微服务一直火,为什么服务化要搞懂?

9. MySQL的COUNT语句,不简单!

10. 漫画:HashSet和TreeSet实现与原理

扫码二维码关注我

·end·

—如果本文有帮助,请分享到朋友圈吧—

我们一起愉快的玩耍!

你点的每个赞,我都认真当成了喜欢

一次关于 Dubbo 服务 IP 注册错误的踩坑经历相关推荐

  1. Dubbo服务的注册与发现

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

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

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

  3. 基于Curator实现dubbo服务自动注册发现

    文章目录 概念 基于ServiceDiscovery实现服务自动注册和发现 Service:服务基本信息 InstanceDetails:封装实例用过来保存到zk中 ServiceProvider:服 ...

  4. dubbo 单元测试_技术分享——一路踩坑构建Dubbo源码

    源码环境 随着目前对技术栈的求知欲,也开始入手Dubbo源码啦!!! 构建源码第一步: 必备开发环境:Java 1.5 以上的版本:Maven 2.2.1 或者以上的版本: 官网下载源代码 官网构建文 ...

  5. 关于又拍云免费cdn全网加速服务的长期评测(各种踩坑)

    妇孺皆知,前端优化中最重要的优化手段之一就是cdn加速,所谓cdn加速就是采用更多的缓存服务器(CDN边缘节点),布放在用户访问相对集中的地区或网络中.当用户访问网站时,利用全局负载技术,将用户的访问 ...

  6. 阿里IOT用AMQP在服务端订阅消息,踩坑

    之前一直按官方文档来的,但是topic消息一直积压,服务端老是订阅不到. 坑:  String iotInstanceId = "${iotInstanceId}"; 这个参数是要 ...

  7. 关于Linux环境下安装配置vsftpd服务全攻略(踩坑)

    2017年08月09日 19:42:19 木大白易 阅读数 17536更多 分类专栏: Linux OS 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接 ...

  8. ABP中服务接口Web.Host部署踩坑

    部署ABP.Web.Host后报如下错误: 后来解决方案是因为服务器没有安装.netframe4.6. 去官网下载了.NDP472-KB4054531-Web.exe 更新了.netframe4.7. ...

  9. vue ssr 服务端跳转刷新 踩坑

    解决方法: 使用 a 标签href属性跳转能刷新当前页面的信息 问题描述: 在ssr渲染期间,普通的this.$router.push的路由跳转不能刷新服务端的数据请求,服务端的数据跳转丢失 出现原因 ...

最新文章

  1. Java:取得当前日期一周之前/之后的日期,或者是一月之前/之后的日期
  2. 群晖 emby_NAS上安装emby,打造家庭媒体中心
  3. python对文件的读操作方法有哪些-python--文件的读写操作
  4. python3精要(51)-json
  5. angular i18n 国际化 多语言
  6. java培训每日总结,这是一份1000多字的Java培训总结,字字珠玑
  7. Android Sensor Driver(四)——IIC总线和驱动
  8. 爬虫从网页中去取的数据中包含nbsp;空格
  9. win32使用拖放文件
  10. python三维数据转换成二维_用Python生成马赛克画
  11. 全球最专业的技术媒体,如何复盘 2019 AI 的发展?
  12. 学习opengl官方指南 01 opengl介绍
  13. Android结束进程的几种方法
  14. Changes to be committed: (use “git restore --staged <file>...“ to unstage)
  15. run和start区别
  16. 金蝶K3 SQL报表系列-委外核销检查表
  17. axios 的 qs库
  18. 【Python】Python脚本命令行解析
  19. 河道中心线提取、平均宽度计算(Arcgis+CAD)
  20. 真太极 太极拳之大概

热门文章

  1. 伺服驱动器生产文件_伺服驱动器程序源代码 程序源代码文件
  2. Ubuntu16.04(Xenial Xerus 好客的非洲地松鼠)更换pip源
  3. oracle中sum求和
  4. 读:Multi-scale pulmonary nodule classification with deep feature fusion via residual network
  5. ssm毕设项目企业门户网站f24qk(java+VUE+Mybatis+Maven+Mysql+sprnig)
  6. 万宁:地产行业如何摆脱“一次性利润”困局?
  7. JS重启自动运行加载视频错误
  8. maven手动导入jar包
  9. 在当当和亚马逊中搜书并输出最低价格
  10. Vmware虚拟机下三种网络模式配置