Dubbo 绑定IP与注册IP获取流程
Dubbo在注册服务时的IP时发现有时候和设想的不一致,会导致联调失败问题,因此这里记录下Dubbo获取BindIp和RegistIp的过程。以便在以后出现问题时能很快锁定位置
Dubbo获取主机IP的过程在服务发布过程中,具体在ServiceConfig#findConfigedHosts,源码如下
private String findConfigedHosts(ProtocolConfig protocolConfig,
List<URL> registryURLs,
Map<String, String> map) {
boolean anyhost = false;
String hostToBind = getValueFromConfig(protocolConfig, DUBBO_IP_TO_BIND);
if (hostToBind != null && hostToBind.length() > 0 && isInvalidLocalHost(hostToBind)) {
throw new IllegalArgumentException("Specified invalid bind ip from property:" + DUBBO_IP_TO_BIND + ", value:" + hostToBind);
}
// if bind ip is not found in environment, keep looking up
if (StringUtils.isEmpty(hostToBind)) {
hostToBind = protocolConfig.getHost();
if (provider != null && StringUtils.isEmpty(hostToBind)) {
hostToBind = provider.getHost();
}
if (isInvalidLocalHost(hostToBind)) {
anyhost = true;
try {
logger.info("No valid ip found from environment, try to find valid host from DNS.");
hostToBind = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
logger.warn(e.getMessage(), e);
}
if (isInvalidLocalHost(hostToBind)) {
if (CollectionUtils.isNotEmpty(registryURLs)) {
for (URL registryURL : registryURLs) {
if (MULTICAST.equalsIgnoreCase(registryURL.getParameter("registry"))) {
// skip multicast registry since we cannot connect to it via Socket
continue;
}
try (Socket socket = new Socket()) {
SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
socket.connect(addr, 1000);
hostToBind = socket.getLocalAddress().getHostAddress();
break;
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
}
if (isInvalidLocalHost(hostToBind)) {
hostToBind = getLocalHost();
}
}
}
}
map.put(BIND_IP_KEY, hostToBind);
// registry ip is not used for bind ip by default
String hostToRegistry = getValueFromConfig(protocolConfig, DUBBO_IP_TO_REGISTRY);
if (hostToRegistry != null && hostToRegistry.length() > 0 && isInvalidLocalHost(hostToRegistry)) {
throw new IllegalArgumentException("Specified invalid registry ip from property:" + DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
} else if (StringUtils.isEmpty(hostToRegistry)) {
// bind ip is used as registry ip by default
hostToRegistry = hostToBind;
}
map.put(ANYHOST_KEY, String.valueOf(anyhost));
return hostToRegistry;
}
BindIp 绑定IP,流程分析: 前一步获取到Ip就不会走下一步
- 从环境变量中获取参数: 参数名称为:DUBBO_IP_TO_BIND
- 从项目配置文件中获取参数: 参数名称为:dubbo.protocols.dubbo.host
- 从InetAddress.getLocalHost().getHostAddress()中获取: 根据本机名称从hosts文件中获取本机IP
- 通过Socket连接注册中心,然后通过Socket获取本机IP
- 轮询本机网卡,直至获取合适的IP
RegistIp 注册IP,流程分析:前一步获取到Ip就不会走下一步
- 从环境变量中获取参数:参数名称为:DUBBO_IP_TO_REGISTRY
- 获取绑定IP