Dubbo应用迁移到Kubernetes

Dubbo是阿里开源的一套服务治理与rpc框架,服务的提供者通过zookeeper把自己的服务发布上去,然后服务调用方通过zk获取服务的ip和端口,dubbo客户端通过自己的软负载功能自动选择服务提供者并调用,整个过程牵涉到的三方关系如下图所示。

Dubbo应用迁移到Kubernetes

在正常的情况下,这三方都在同一个互通的网段,provider提供给zk的就是获取到的本机地址,consumer能访问到这个地址。

但是假如服务放在docker容器中,而调用者并不在docker中,它们的网段是不一样的。

Dubbo应用迁移到Kubernetes

这个时候就出现问题了,consumer无法访问到provider了。

Dubbo提供的解决方案

新版的Dubbo提供了四个配置来指定与注册服务相关的地址和端口。

DUBBO_IP_TO_REGISTRY: 要发布到注册中心上的地址 DUBBO_PORT_TO_REGISTRY: 要发布到注册中心上的端口 DUBBO_IP_TO_BIND: 要绑定的服务地址(监听的地址) DUBBO_PORT_TO_BIND: 要绑定的服务端口

以IP地址为例,Dubbo先找是不是有DUBBO_IP_TO_BIND这个配置,如果有使用配置的地址,如果没有就取本机地址。然后继续找DUBBO_IP_TO_REGISTRY,如果有了配置,使用配置,否则就使用DUBBO_IP_TO_BIND。具体代码如下:

/** * 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 * * @param protocolConfig * @param registryURLs * @param map * @return */ private static String findConfigedHosts(ServiceConfig<?> sc, 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 (sc.getProvider() != null && StringUtils.isEmpty(hostToBind)) { hostToBind = sc.getProvider().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; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/6c3a9f62a1fcf8b41c92b421fd577450.html