dubbo注册服务IP解析异常及IP解析源码分析
在使用dubbo注册服务时会遇到IP解析错误导致无法正常访问.
比如: 本机设置的IP为172.16.11.111, 但实际解析出来的是180.20.174.11
这样就导致这个Service永远也无法被访问到, 而调用方一直报错.
当然若发现服务无法访问, 最好先通过dubbo-admin后台排查下注册的服务是否正常.
IP解析异常时的解决方法:
- 绑定hostname+ip
1. 先查看机器的hostname
2. 修改hosts文件, 增加hostname 172.16.11.111
- 配置nameserver
排查机器上配置的nameserver是否有问题, 若存在无用的nameserver则直接删掉
- 在dubbo的配置文件中写死host
<dubbo:protocol host="172.16.11.111"/>
或者在每个provider中绑定host
<dubbo:provider host="172.16.11.111">
最好不要用第三种方式, 限制太多. 而且如果这样做了就不支持集群了.
dubbo的官网也不建议使用这种方式. 请慎用.
dubbo获取IP源码分析
/**
* 判断host是否为不可用的本地Host
*/
public static boolean isInvalidLocalHost(String host) {
return host == null
|| host.length() == 0
|| host.equalsIgnoreCase("localhost")
|| host.equals("0.0.0.0")
|| (LOCAL_IP_PATTERN.matcher(host).matches());
}
/**
* 获取本地Host.
* 若address == null ? "127.0.0.1" : InetAddress.getHostAddress();
*/
public static String getLocalHost(){
InetAddress address = getLocalAddress();
return address == null ? LOCALHOST : address.getHostAddress();
}
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
...
...
//1. 先从ProtocolConfig中取host. 若没有配置则为null
String host = protocolConfig.getHost();
//2. 再从ProviderConfig中取host. 若没有配置则为null
if (provider != null && (host == null || host.length() == 0)) {
host = provider.getHost();
}
boolean anyhost = false;
//3. 若取出的是本地host, 则继续取host
if (NetUtils.isInvalidLocalHost(host)) {
anyhost = true;
try {
//4. 通过InetAddress的方式获取Host
//默认读取本机hosts中hostname对应的IP
//如: 你在hosts中配置了 leo 172.16.11.111
//则读取的IP就是172.16.11.111
host = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
logger.warn(e.getMessage(), e);
}
if (NetUtils.isInvalidLocalHost(host)) {
if (registryURLs != null && registryURLs.size() > 0) {
for (URL registryURL : registryURLs) {
try {
Socket socket = new Socket();
try {
//5. 通过Socket的方式获取Host
//一般解析到这里, 都会获取到正确的本地IP, 除非你有多网卡, 或者有VPN, 导致无法正常解析.
SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
socket.connect(addr, 1000);
host = socket.getLocalAddress().getHostAddress();
break;
} finally {
try {
socket.close();
} catch (Throwable e) {}
}
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
}
//6. 遍历本地网卡, 返回第一个合理的Host
//最后一个大招. 当上述都解析不到时, 则会遍历本地网卡.
//逐个获取IP, 直到有一个合理的IP为止.
if (NetUtils.isInvalidLocalHost(host)) {
host = NetUtils.getLocalHost();
}
}
}
...
}
/**
* 遍历本地网卡,返回第一个合理的IP。
* @return 本地网卡IP
*/
public static InetAddress getLocalAddress() {
if (LOCAL_ADDRESS != null)
return LOCAL_ADDRESS;
InetAddress localAddress = getLocalAddress0();
LOCAL_ADDRESS = localAddress;
return localAddress;
}
/**
* 遍历本地网卡,返回第一个合理的IP。
* @return 本地网卡IP
*/
private static InetAddress getLocalAddress0() {
InetAddress localAddress = null;
try {
localAddress = InetAddress.getLocalHost();
if (isValidAddress(localAddress)) {
return localAddress;
}
} catch (Throwable e) {
logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
}
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
if (interfaces != null) {
while (interfaces.hasMoreElements()) {
try {
NetworkInterface network = interfaces.nextElement();
Enumeration<InetAddress> addresses = network.getInetAddresses();
if (addresses != null) {
while (addresses.hasMoreElements()) {
try {
InetAddress address = addresses.nextElement();
if (isValidAddress(address)) {
return address;
}
} catch (Throwable e) {
logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
}
}
}
} catch (Throwable e) {
logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
}
}
}
} catch (Throwable e) {
logger.warn("Failed to retriving ip address, " + e.getMessage(), e);
}
logger.error("Could not get local host ip address, will use 127.0.0.1 instead.");
return localAddress;
}
dubbo注册服务IP解析异常及IP解析源码分析的更多相关文章
- 微服务架构 | *3.5 Nacos 服务注册与发现的源码分析
目录 前言 1. 客户端注册进 Nacos 注册中心(客户端视角) 1.1 Spring Cloud 提供的规范标准 1.2 Nacos 的自动配置类 1.3 监听服务初始化事件 AbstractAu ...
- 微服务之SpringCloud实战(四):SpringCloud Eureka源码分析
Eureka源码解析: 搭建Eureka服务的时候,我们会再SpringBoot启动类加上@EnableEurekaServer的注解,这个注解做了一些什么,我们一起来看. 点进@EnableEure ...
- 🏆【Alibaba微服务技术系列】「Dubbo3.0技术专题」回顾Dubbo2.x的技术原理和功能实现及源码分析(温故而知新)
RPC服务 什么叫RPC? RPC[Remote Procedure Call]是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范.它允许程序调用另一个地址空间(通常是共享网络的另 ...
- dubbo负载均衡策略及对应源码分析
在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用.我们还可以扩展自己的负责均衡策略,前提是你已经从一个小白变成了大牛,嘻嘻 1.Random LoadBalance 1 ...
- Dubbo 源码分析 - 服务导出
1.服务导出过程 本篇文章,我们来研究一下 Dubbo 导出服务的过程.Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可 ...
- dubbo源码分析02:服务引用
一.何时创建服务引用 引用官方文档的原话,如果将Dubbo托管在Spring-IOC容器下,Dubbo服务引用的时机有两个,第一个是在Spring容器调用ReferenceBean的afterProp ...
- Dubbo 源码分析 - 服务引用
1. 简介 在上一篇文章中,我详细的分析了服务导出的原理.本篇文章我们趁热打铁,继续分析服务引用的原理.在 Dubbo 中,我们可以通过两种方式引用远程服务.第一种是使用服务直联的方式引用服务,第二种 ...
- spring cloud EurekaClient 多网卡 ip 配置 和 源码分析(转)
https://blog.csdn.net/qq_30062125/article/details/83856655 1.前言对于spring cloud,各个服务实例需要注册到Eureka注册中心. ...
- 源码分析Dubbo服务消费端启动流程
通过前面文章详解,我们知道Dubbo服务消费者标签dubbo:reference最终会在Spring容器中创建一个对应的ReferenceBean实例,而ReferenceBean实现了Spring生 ...
随机推荐
- 【HDU 4372】 Count the Buildings (第一类斯特林数)
Count the Buildings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- ANDROID_MARS学习笔记_S04_007_从服务器获取微博数据时间线
一.代码 1.xml(1)activity_main.xml <?xml version="1.0" encoding="utf-8"?> < ...
- Cocos2d—X游戏开发之CCScrollView(滑动视图)(十二)
CCScrollView在Cocos2d-X引擎中主要使用在图片尺寸远大于屏幕尺寸的时候使用. 总体来说,使用起来比较简单. 一个是CCScrollView控件本身,一个是CCScrollViewDe ...
- 透过表象看本质!?之二——除了最小p乘,还有PCA
如图1所示,最小p乘法求得是,而真实值到拟合曲线的距离为.那么,对应的是什么样的数据分析呢? 图1 最小p乘法的使用的误差是.真实值到拟合曲线的距离为 假如存在拟合曲线,设直线方程为.真实值到该曲线的 ...
- ASP.NET之JSONHelper操作
转自:http://www.cnblogs.com/PEPE/archive/2012/02/13/Pepe_Yu.html 之前说到了Ext.Net中GridPanel行取值的问题(Ext.Net开 ...
- zoj 3620 Escape Time II
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4744 Escape Time II Time Limit: 2 Seconds ...
- c++通过jnihelper调用java方法刷新androidUI的注意事项
2dx android项目需接入第三方sdk完成支付,玩家点击充值界面,通过jnihelper来调用java的方法并弹出android组件界面,之前采用直调的简单方法,顺利的把参数传到java层,但后 ...
- 有7g和2g的砝码各一个,怎样称可以3次把140g东西分为50g和90g???????
第一次:等分 50和90为 70 70 2. 7g 和2g ,取出一个70中的9g , 61 70 3.利用 9g和2g砝码,取出61中的11克,前面的9 和 11 都放进70
- Oracle 视图添加主键
在Entity Framework中,从数据库生成模型,视图常报无主键. 解决办法:为试图添加主键/复合主键 create or replace view view_activebudgetamoun ...
- poj 2079 Triangle(旋转卡壳)
Triangle Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 8917 Accepted: 2650 Descript ...