個人ブログのアドレスstudyidea.cn、より多くのオリジナルの記事をクリックしてください
段付ピット
同社は最近、部屋を作成した後、あなたは新しい部屋に既存のシステムの展開を同期させる必要があり、展開が完了すると、同時に2つの部屋には、サービスを提供します。下に示すように、システム・アーキテクチャ:
このシステムは、現在、外部の使用しているRestful
リモートの内部使用へのインタフェースDubbo
サービス登録センターをzookeeper
。現在設定されているサービスがこの客室サービスに呼び出されます。
エンジンルーム内の旧サービス、新しい部屋のためにBの部屋。展開が完了した後にB室、エンジンルームBシステムの可用性をテストする必要があります。製造試験は、Bが部屋にもルームサービスを呼び出すことがわかりました。
A / B各オープンルームネットワークが相互にアクセスすることができます
調査を通じてルームサービスのログB、見つかったService B
サービスノードが登録IP解析エラーを、機械室B IPは、機械室に解決IPを。
だから、ときBテストトラフィックルームに、openapi
サービスは、不正なレジストリに至るまで取得Service B
ルームサービスと呼ばれるサービスアドレス、。以下に簡略化され、図が呼び出されます。
知識ポイント:(サービスプロバイダーが開始ダボサービスアドレス意志IPレジストリに登録+ポート)は、(消費者が起動したときに、レジストリを介してサービスプロバイダのアドレスを取得するIP +ポート)を、フォローアップのサービスコールを指示しますサービスアドレスを介して直接呼び出し。
分析
デバッグ Dubbo
に位置するソースIP
コードの構文解析を、配置されているServiceConfig#findConfigedHosts
、以下のソースコード:
ダボバージョン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#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