dubbo注册服务IP解析异常及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; }
文章转自:http://www.cnblogs.com/leo-li-3046/p/5702479.html
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Spring Boot + Mybatis + Redis二级缓存(Java Web现代化开发)
背景 SpringBoot因其提供了各种开箱即用的插件,使得它成为了当今最为主流的Java Web开发框架之一。Mybatis是一个十分轻量好用的ORM框架。Redis是当今十分主流的分布式key-value型数据库,在web开发中,我们常用它来缓存数据库的查询结果。 本篇博客将介绍如何使用SpringBoot快速搭建一个Web应用,并且采用Mybatis作为我们的ORM框架。为了提升性能,我们将Redis作为Mybatis的二级缓存。为了测试我们的代码,我们编写了单元测试,并且用H2内存数据库来生成我们的测试数据。通过该项目,我们希望读者可以快速掌握现代化Java Web开发的技巧以及最佳实践。 本文的示例代码可在Github中下载:https://github.com/Lovelcp/spring-boot-mybatis-with-redis/tree/master 环境 开发环境:mac 10.11 ide:Intellij 2017.1 jdk:1.8 Spring-Boot:1.5.3.RELEASE Redis:3.2.9 Mysql:5.7 Spring-Boot 新建...
- 下一篇
安装Dubbo管理控制台
样例参考视频:http://www.roncoo.com/course/view/f614343765bc4aac8597c6d8b38f06fd Dubbo管控台可以对注册到zookeeper注册中心的服务或服务消费者进行管理,但管控台是否正常对Dubbo服务没有影响,管控台也不需要高可用,因此可以单节点部署。 IP: 192.168.3.71 部署容器:apache-tomcat-7.0.57 端口:8080 1、 下载最新版的Tomcat7: $wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-7/v7.0.57/bin/apache-tomcat-7.0.57.tar.gz 2、 解压: $ tar -zxvf apache-tomcat-7.0.57.tar.gz $ mv apache-tomcat-7.0.57 dubbo-admin-tomcat 3、 移除/home/wusc/dubbo-admin-tomcat/webapps目录下的所有文件: $ rm -rf * 4、 上传Dubbo管理控制台程序...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装