今天在跑dubbo 的 DemoService 2.5.4-SNAPSHOT版本的时候,遇到到一个奇怪的问题。consumer怎么都连接不上provider的服务。最后才发现是由于dubbo自 己实现的检测本地IP地址代码不够强壮造成的。你这里的provider实际上是运行在A地址上,但是dubbo检测到本地的IP地址是B,然后他在 zookeeper上注册自己的服务地址的时候,用的是这个B这个IP地址,那么当consumer连接到zookeeper上的时候,查询到 DemoService是在B上的,显然这个IP地址上并没有这样的dubbo服务,那么这个consumer就肯定不能成功。

为什么dubbo检测本地IP地址的结果是错的,因为dubbo检测本地IP地址的策略是先调用InetAddress.getLocalHost,如果
该方法返回一个合法的地址,则直接认为是本地的IP地址,否则会枚举本地所有网卡,并返回第一个合法的IP地址作为本地地址。

坑爹的就是InetAddress.getLocalHost返回了一个错误的IP地址。为什么这个函数会返回一个错误的地址,因为这个函数的原理是通过
获取本机的hostname,然后对此hostname做解析,从而获取IP地址的。那么问题来了,如果在本机的/etc/hosts文件里对这个主机名
指向了一个错误的IP地址,那么InetAddress.getLocalHost就会返回这个错误的IP地址。当然如果你的hostname是到DNS
去解析的,碰巧DNS上的信息也是错的,也同样是悲惨结局。

遇到同样问题的人,可以先检查下hosts文件的设置里面A地址指向哪里了,然后看一下DNS解析出的地址。当然如果dubbo的代码检查一下,这个返回
的地址,是不是真的是本机的IP地址,也不会出现这个问题了,归根结底还是dubbo的卡发人员太相信InetAddress.getLocalHost
了,这货自己应该确保不会出现这样的乌龙事件的。你返回一个不是本机的IP地址作为本机的IP地址,这个在语义上就错误了。不管你用了多么愚蠢的算法,结
果就是不应该返回一个不是本地的IP地址作为本地的地址,不是吗?否则还叫什么狗屁get local host!!!

我为什么说InetAddress.getLocalHost的算法是愚蠢的,是因为这个尽管可能会被hosts文件和DNS误导,但是显然这两个地方都
不是本机IP地址的权威获取处,权威获取处是网卡本身的配置信息。即便你要使用一个不靠谱来源的信息,你至少跟本机的网卡地址做一下校验嘛!如果你实在是
不知道怎么获取,抛出个异常说明一下你的无能为力,大家也是可以接受的嘛!犯不着给个错误的信息,让这么多人掉坑里,浪费时间,对不对?

最后,dubbo检测本地地址的代码位于:
dubbo-common/src/main/java/com/alibaba/dubbo/common/utils/NetUtils.java里的getLocalAddress函数,可以看一下。

坑爹的InetAddress getLocalHost函数的更多相关文章

  1. InetAddress.getLocalHost() 执行很慢?

    背景介绍 某次在 SpringBoot 2.2.0 项目的一个配置类中引入了这么一行代码: InetAddress.getLocalHost().getHostAddress() 导致项目启动明显变慢 ...

  2. at java.net.InetAddress.getLocalHost(InetAddress.java:1475)

    今天在centos 安装hadoop安装完成后执行wordcount的时候报如下错误: at java.net.InetAddress.getLocalHost(InetAddress.java:14 ...

  3. mac系统InetAddress.getLocalHost().getHostAddress() 很慢

    java.net.InetAddress.getLocalHost() 这个调用在新版的mac os中可能会耗时很久. 解决办法有两种: 1. 就是把本机的hostname 添加到 hosts 中,例 ...

  4. jmeter的新增函数说明

    本文算是对<零成本实现Web性能测试:基于Apache JMeter>中的<详解JMeter函数和变量>进行狗尾续貂哈,因为最近版本的jmeter增加了几个新函数,在原书中没有 ...

  5. Spark远程调试函数

    Spark远程调试函数 1.sendInfo 该函数用于分布式程序的调试,非常方便,在spark的rdd操作中嵌入sendInfo,启动nc服务器后,可以收集到所有需要的运行时信息,该函数可以捕获ho ...

  6. java:网络编程(InetAddress,InetSocketAddress,URL,TCP(Socket与SeverSocket),TCP与UDP的区别)

    InerAddress: /**IP地址:在网络上唯一标示一台计算机 * 端口号:标示计算机上不同的应用程序 * java.net.InetAddress类:此类表示互联网协议 (IP) 地址. * ...

  7. ES6 箭头函数中的 this?你可能想多了(翻译)

    箭头函数=>无疑是ES6中最受关注的一个新特性了,通过它可以简写 function 函数表达式,你也可以在各种提及箭头函数的地方看到这样的观点——“=> 就是一个新的 function”. ...

  8. java中Inetaddress类

    InetAddress类 InetAddress类用来封装我们前面讨论的数字式的IP地址和该地址的域名. 你通过一个IP主机名与这个类发生作用,IP主机名比它的IP地址用起来更简便更容易理解. Ine ...

  9. InetAddress类

    InetAddress类是Java对IP地址(包括IPv4和IPv6)的高层表示.大多数其他网络类都要用到这个类,包括Socket,ServerSocket,URL,DatagramSocket,Da ...

随机推荐

  1. Puppet的搭建和应用

    Puppet的部署与应用 1. 案例概述 作为一名系统管理员,维护服务器正常运行是最基本的职责,在管理几台到几十台服务器时,大部分管理员喜欢自己写小工具来维护,但随着服务器的数量曾多,任务量也逐渐增多 ...

  2. LinkedHashMap

    LinkedHashMap既是一个HashMap,也是一个链表 package java.util; import java.util.function.Consumer; import java.u ...

  3. Android Java语法学习

    Activity中有一个名称叫onCreate的方法.该方法是在Activity创建时被系统调用,是一个Activity生命周期的开始. onCreate方法的参数savedInstanceState ...

  4. python第四十九天--paramiko模块安装大作战

    准备开始学习:paramiko模块,发现这个模块十分难搞 安装不上 搞了半天,win10 64下 pytyon 3.6 的 paramiko模块 死活安不上,在网上不断的找资料,可是没有用,没有用啊 ...

  5. MySQL 8.0 —— CATS事务调度算法的性能提升

    原文地址:https://mysqlserverteam.com/contention-aware-transaction-scheduling-arriving-in-innodb-to-boost ...

  6. C#检测U盘是否插入

    public partial class Form1 : Form { #region u盘属性 public const int WM_DEVICECHANGE = 0x219;//U盘插入后,OS ...

  7. CRM 各种类型字段的 赋值 取值

    //lookupRecordEntity["new_lead"] = new EntityReference(entity.LogicalName, entity.Id); 获取时 ...

  8. [MapReduce_7] MapReduce 中的排序

    0. 说明 部分排序 && 全排序 && 采样 && 二次排序 1. 介绍 sort 是根据 Key 进行排序 [部分排序] 在每个分区中,分别进行排序 ...

  9. 命令行方式安装Pycharm

    sudo apt install snapd snapd-xdg-open snap refresh sudo snap install pycharm-professional --classic

  10. ST_Geometry效率的测试与分析

    测试环境 数据库:Oracle11g R1(11.1.0.6) 64Bit 中间件:ArcSDE10 (64Bit) 数据情况:点数据(point,231772条记录),面数据(poly,12条记录) ...