You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by GitBox <gi...@apache.org> on 2022/03/05 04:57:25 UTC

[GitHub] [dubbo] VirensCn commented on issue #9737: 在安装了docker的机器上启动dubbo服务,provider取到的host始终是docker网段的ip

VirensCn commented on issue #9737:
URL: https://github.com/apache/dubbo/issues/9737#issuecomment-1059686917


   是他们改了代码,去掉了这部分[ServiceConfig.java](https://github.com/apache/dubbo/commit/901cf6f60c1c72ebb0659d77f4569b87f51bad40#diff-b90db27a4d125d825b93979c962b2d2e7d8c69d2528c0404d4a6ea7cd03169b0)
   
   ![image](https://user-images.githubusercontent.com/9736815/156868360-a77349ad-9d7a-4fab-adc5-79d2b825d48d.png)
   
   以前会尝试连接注册中心,然后从Socket中获取本地IP,现在直接获取网卡的了。。
   
   我现在是在启动时,先获取IP然后存环境变量后正常启动
   ![image](https://user-images.githubusercontent.com/9736815/156868533-43603ab5-dd5a-444e-8d92-4849abcbdb36.png)
   
   `
   
   import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_IP_TO_BIND;
   
   import java.lang.reflect.Method;
   import java.net.InetAddress;
   import java.net.NetworkInterface;
   import java.util.Enumeration;
   import java.util.List;
   import java.util.regex.Pattern;
   
   import org.apache.dubbo.common.utils.NetUtils;
   import org.slf4j.Logger;
   import org.slf4j.LoggerFactory;
   
   import cn.hutool.core.net.NetUtil;
   import cn.hutool.core.util.ReflectUtil;
   import cn.hutool.core.util.StrUtil;
   import cn.virens.common.exception.APIException;
   import cn.virens.common.exception.ExceptionUtil;
   
   public class DubboNet {
   	private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
   
   	private static Logger logger = LoggerFactory.getLogger(DubboNet.class);
   
   	private static final String DOCKER_GWBRIDGE = "172.18.";
   	private static final String DOCKER_INGRESS = "10.0.0.";
   
   	/** 初始化dubbo默认绑定的IP地址(是否覆盖环境变量) */
   	public static void initDubboIpToBind(boolean replace) throws APIException {
   		String last = System.getProperty(DUBBO_IP_TO_BIND);
   		if (last == null || last.isEmpty() || replace) {
   			setDubboIpToBind(getLocalHost());
   		}
   	}
   
   	/** 必须要在dubbo应用启动之前调用 */
   	private static void setDubboIpToBind(String host) throws APIException {
   		System.setProperty(DUBBO_IP_TO_BIND, host);
   	}
   
   	/** 获取dubbo默认绑定的IP地址 */
   	public static String getDubboIpToBind() throws APIException {
   		return System.getProperty(DUBBO_IP_TO_BIND);
   	}
   
   	/** 获取当前有效的IP,主要是屏蔽了docker_gwbridge的IP端 */
   	public static String getLocalHost() throws APIException {
   		for (NetworkInterface network : getNetworkInterfaces()) {
   			String host = getHostAddress(network);//
   
   			if (host != null && !host.isEmpty()) {
   				return host;//
   			}
   		}
   
   		return NetUtil.getLocalhostStr();
   	}
   
   	private static String getHostAddress(NetworkInterface inter) throws APIException {
   		Enumeration<InetAddress> enumer = inter.getInetAddresses();
   
   		while (enumer != null && enumer.hasMoreElements()) {
   			InetAddress addr = enumer.nextElement();
   
   			if (Boolean.TRUE.equals(isValidHost(addr))) {
   				return addr.getHostAddress();//
   			}
   		}
   
   		return null;
   	}
   
   	/** 获取有效的网卡列表 */
   	private static List<NetworkInterface> getNetworkInterfaces() throws APIException {
   		return ExceptionUtil.safe1(logger, () -> invokeStatic("getValidNetworkInterfaces"));
   	}
   
   	/** 验证地址是否有效(是否可到达) */
   	private static Boolean isValidHost(InetAddress addr) throws APIException {
   		if (addr != null && isValidHost(addr.getHostAddress())) {
   			return ExceptionUtil.safe1(logger, () -> {
   				return addr.isReachable(100);
   			});
   		} else {
   			return false;
   		}
   	}
   
   	/** 验证地址是否有效(IP格式正确) */
   	private static boolean isValidHost(String addr) throws APIException {
   		if (addr != null && IP_PATTERN.matcher(addr).matches()) {
   			if (StrUtil.startWith(addr, DOCKER_GWBRIDGE)) {
   				return false;//
   			}
   
   			if (StrUtil.startWith(addr, DOCKER_INGRESS)) {
   				return false;//
   			}
   
   			return NetUtils.isValidLocalHost(addr);
   		} else {
   			return false;
   		}
   	}
   
   	/** 调用Dubbo.NetUtils的私有静态方法 */
   	@SuppressWarnings("unchecked")
   	private static <R> R invokeStatic(String methodName) throws APIException {
   		Method method = ReflectUtil.getMethodByName(NetUtils.class, methodName);
   
   		if (method != null) {
   			return (R) ReflectUtil.invokeStatic(method);
   		} else {
   			return null;
   		}
   	}
   }
   `
   
   `	private static final String DOCKER_GWBRIDGE = "172.18.";
   	private static final String DOCKER_INGRESS = "10.0.0.";`
   这2个是需要被过滤掉的,据观察docker swarm 的容器中有2个无用IP端,这2个还会优先有效的,所以需要过滤,可以自行判断需要过滤的IP端。。
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org