程序猿
微录

Dubbo 绑定IP与注册IP获取流程

程序猿微录 发布于: 2020-08-18 03:14 114 0 0 0
首页
文章
专栏
问答
寄语
公告
  • 前往登录

Dubbo 绑定IP与注册IP获取流程

程序猿微录 发布于 2020-08-18 03:14 114 0 0 0
所属文册: Alibaba 文章标签: Dubbo

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就不会走下一步

  1. 从环境变量中获取参数: 参数名称为:DUBBO_IP_TO_BIND
  2. 从项目配置文件中获取参数: 参数名称为:dubbo.protocols.dubbo.host
  3. 从InetAddress.getLocalHost().getHostAddress()中获取: 根据本机名称从hosts文件中获取本机IP
  4. 通过Socket连接注册中心,然后通过Socket获取本机IP
  5. 轮询本机网卡,直至获取合适的IP

RegistIp 注册IP,流程分析:前一步获取到Ip就不会走下一步

  1. 从环境变量中获取参数:参数名称为:DUBBO_IP_TO_REGISTRY
  2. 获取绑定IP