范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

记一次处理Dubbo多网卡注册IP错误问题

  场景介绍
  今天在docker上部署服务时,启动都很成功,但是访问时却访问失败。之前在本地启动、在测试服k8s上启动都很正常,为什么同样的代码、同样的docker镜像在docker上却有问题呢?真让人摸不着头脑。
  服务是部署在docker集群上,因为是部署测试,就准备了3台机器,由3台机器组成的一个集群。服务是按业务划分,分别写在不同的docker-compose.yml文件中,最后通过docker stack 启动。
  dubbo的注册中心使用的是nacos。
  因为在本地测试正常,而且也在k8s上部署且访问正常,所以在docker环境启动也很顺利。唯一不行的就是docker环境部署后部分接口访问报错。过程排查
  在接口访问失败后,立刻查看了服务日志,报错是dubbo接口调用超时。错误如下:org.apache.dubbo.rpc.RpcException:  Failed to invoke the method getExportedURLs in the service org.apache.dubbo.rpc.service.GenericService.  Tried 1 times of the providers [172.18.0.3:20881] (1/1) from the registry 172.10.36.101:8848 on the consumer 172.19.0.7 using the dubbo version 2.7.17. …省略一大堆… error message is:Host is unreachable: /172.18.0.3:20881 复制代码
  从报错日志来看,有个明显的错误是Host is unreachable。现在是服务C调用服务A的dubbo接口调用不到,用我蹩脚的英文理解刚才错误信息是主机不可达。
  此时,有两个疑问出现在容量不够大的脑子里:为什么服务C调用不了服务A?172.18.0.3这个ip是什么东东,哪里来的。
  针对问题1,首先想到的是服务A没有注册到nacos里去,打开nacos控制台发现服务A是已经注册上去了的,并且发现注册的ip是172.18.0.3,刚好和问题2里的ip一致。
  既然服务已经正常注册,那就剩下172.18.0.3这个ip是哪里来的了。通过docker exec命令进入服务A容器,使用命名ifconfig看下服务A的ip信息:
  找到了,是服务A容器的一个网卡地址,不过这个容器怎么网卡?难道是因为多个网卡导致的吗?那为什么部署在k8s容器里没有问题?难道k8s里面没有多个网卡吗?又接着一连串的问号在脑海里出现了?
  先看看,k8s里的ip信息吧。通过kubectl exec登录容器, 查看ip信息ip addr。嗯?只有两个,比docker里少了好多。
  看来是,dubbo注册的时候,选择网卡的时候,是有一定的机制的,选择的不是我想要的。看看源码吧,到底是怎么选择的。源码分析
  Dubbo获取网卡地址的逻辑是在org.apache.dubbo.common.utils.NetUtils类中getLocalAddress0方法。private static InetAddress getLocalAddress0() {     InetAddress localAddress = null;      // @since 2.7.6, choose the {@link NetworkInterface} first     try {         NetworkInterface networkInterface = findNetworkInterface();         Enumeration addresses = networkInterface.getInetAddresses();         while (addresses.hasMoreElements()) {             Optional addressOp = toValidAddress(addresses.nextElement());             if (addressOp.isPresent()) {                 try {                     if (addressOp.get().isReachable(100)) {                         return addressOp.get();                     }                 } catch (IOException e) {                     // ignore                 }             }         }     } catch (Throwable e) {         logger.warn(e);     }      try {         localAddress = InetAddress.getLocalHost();         Optional addressOp = toValidAddress(localAddress);         if (addressOp.isPresent()) {             return addressOp.get();         }     } catch (Throwable e) {         logger.warn(e);     }       return localAddress; } 复制代码
  这块代码的整体逻辑还是很好理解的:查找所有的网卡校验网卡对应的ip是否合适如果找不到合适的ip,则设置ip为127.0.0.1
  再看下Dubbo是如何校验ip是否合适的呢?对应方法为toValidAddressprivate static Optional toValidAddress(InetAddress address) {     if (address instanceof Inet6Address) {         Inet6Address v6Address = (Inet6Address) address;         if (isPreferIPV6Address()) {             return Optional.ofNullable(normalizeV6Address(v6Address));         }     }     if (isValidV4Address(address)) {         return Optional.of(address);     }     return Optional.empty(); } 复制代码
  先判断拿到的地址是否为ipv6,再看是否设置了优先选择ipv6,即有没有配置java.net.preferIPv6Addresses=true,我们项目配置的是java.net.preferIPv4Stack=true,所以走的是下面的逻辑。再检测是否是合法的ipv4地址,拿到ip后,检查ip的网速,如果响应时间为100ms内,则把这个ip作为注册ip。
  知道了Dubbo是如何选择网卡的了,但是好像对我们没有太大帮助,我总不能限制网卡的网速去吧?
  最好的办法还是,我是否可以设置?再看一遍源码是不是遗漏了什么。看下是如何选择网卡的:public static NetworkInterface findNetworkInterface() {      List validNetworkInterfaces = emptyList();     try {         // 寻找合适的网卡         validNetworkInterfaces = getValidNetworkInterfaces();     } catch (Throwable e) {         logger.warn(e);     }      NetworkInterface result = null;      // Try to find the preferred one     for (NetworkInterface networkInterface : validNetworkInterfaces) {         // 是否为优选的网卡         if (isPreferredNetworkInterface(networkInterface)) {             result = networkInterface;             break;         }     }      if (result == null) { // If not found, try to get the first one         for (NetworkInterface networkInterface : validNetworkInterfaces) {             Enumeration addresses = networkInterface.getInetAddresses();             while (addresses.hasMoreElements()) {                 Optional addressOp = toValidAddress(addresses.nextElement());                 if (addressOp.isPresent()) {                     try {                         if (addressOp.get().isReachable(100)) {                             return networkInterface;                         }                     } catch (IOException e) {                         // ignore                     }                 }             }         }     }      if (result == null) {         result = first(validNetworkInterfaces);     }      return result; } 复制代码
  这方法也分为几步,也是很好理解的:查找所有合适的网卡在查找的网卡里遍历一遍,看是否有优先设置的如果没有,选择一个网速100毫秒响应的如果还没有,则返回第一个网卡
  第一步,查找所有合适的网卡,怎么算合适的呢?getValidNetworkInterfaces方法里判断只要不是被忽略的网卡就是合适的,里面的代码就不细看了,大致逻辑是,通过参数dubbo.network.interface.ignored可以设置哪些网卡被忽略,如果忽略多个可以用逗号拼接。例如dubbo.network.interface.ignored=eth0,eth1。这个参数好像可以满足我们的需求。
  第二步,查找网卡是否有被我们优先设置的。isPreferredNetworkInterface方法我们看下:public static boolean isPreferredNetworkInterface(NetworkInterface networkInterface) {     // dubbo.network.interface.preferred     String preferredNetworkInterface = System.getProperty(DUBBO_PREFERRED_NETWORK_INTERFACE);     return Objects.equals(networkInterface.getDisplayName(), preferredNetworkInterface); } 复制代码
  可以看到,我们可以通过DUBBO_PREFERRED_NETWORK_INTERFACE这个参数,也就dubbo.network.interface.preferred来指定网卡。例如:dubbo.network.interface.preferred=eth0。
  看到这里,我们就明白了,至少我们可以通过排除网卡或者设置网卡来让Dubbo选择合适的ip去注册。因为docker容器里,不一定有多少个确定的网卡,还是指定网卡比较保险。问题解决
  好了,知道如何让Dubbo来选择网卡了,我们只要找到各个容器里在同一网段的网卡就好了。
  于是,登录到各个docker容器里,查看ip信息。对比了一下,发现eth1这个ip的网段都是10.10.x.x网段的。
  配置环境变量信息dubbo.network.interface.preferred=eth1,重启服务,然后访问接口,果然通了。
  大功告成!后记
  其实,还有其他办法来解决问题,比如:protocol配置host信息、设置 DUBBO_IP_TO_REGISTRY和DUBBO_IP_TO_BIND等。这里就不展开说明了,有兴趣的小伙伴可以自己试一试。

小小燕麦还能这样吃?垦荒人带你吃出不同花样清明节是我国的一项传统节日,每年的四月份都会有,清明节期间是一个比较适合养生的时间段,而养生一般较好的食物就是五谷杂粮,五谷杂粮的营养价值比较高种类多,适量食用具有一定增强人体免疫人老之后,睡觉之前多做这几种事,一般都会长寿前言,老年之后我们一定要明白,有些事情可以做有些事情不可以做,特别是在睡觉之前一定要掌握好自己的生活规律,不然的话会影响到自己的身体健康,想要老年之后更长寿,就必须做好自己该做的事鸡蛋不能多吃?浙大研究多吃一个蛋,死亡风险增加!这能信吗?鸡蛋的营养价值有目共睹,作为最优质的蛋白质和脂肪来源,一直活跃在老百姓的餐桌上,但随着人们健康意识的提高,针对鸡蛋一类的经典食品,也开始用批判的眼光进行看待。一直以来,都有各种各样养生从肠道开始,中老年人要常吃8宝,调理肠胃,健康少生病春季气温变化大,早晚温差较大,大家要注意调理肠道,除了好的生活习惯外,饮食调理也很重要。在生活中,平衡饮食,少酸少辣多蔬菜,促进消化,清洁肠道,建议中老年人,要常吃这8宝粗纤维蔬菜清明易肝火旺,保持情志舒畅清明,是24节气中的第5个节气。就中医养生来讲,清明时节是一年之中养生的重要时期。过了清明节,万物舒展,中医认为人应四时,春季万物生长,机体也是如此。最近一段时候,上海市民配合防疫健康长寿从早起开始,做好4件事,多吃5果,牢记1念,预防疾病健康长寿是我们每个人毕生追求的,但是这种追求可望而不可及,随着年龄的增长,疾病会接踵而至,这是衰老导致的。我们能做的,就是延缓衰老,让身体少生病,从而使自己健康多一点,疾病少一点。詹姆斯退役后,联盟第一人的宝座应当归属于谁?仅这4人有资格詹姆斯虽然已经37岁了但是状态和数据都保持的很好任何拥有他的球队都是每年的夺冠热门球队,但是詹姆斯近年来,受伤越来越频繁,运动能力也有所下降。虽然我们不愿意面对,但是詹姆斯注定在未回看朱彦西翟晓川大闹CBA,冲突女记者,北京首钢输吉林真的不冤回看翟晓川朱彦西冲突女记者,大闹CBA,就不难理解为何北京首钢会输给吉林,真的不冤。大家好我是毛罗,1月9号的事情,相信很多的球迷朋友还记忆犹新。当时北京首钢在吉林赛区跟吉林队打比雅尼斯辞职,闵鹿蕾出山?首钢打包4人,秦晓雯看走眼忍痛割爱雅尼斯辞职,闵鹿蕾出山?首钢打包4人,秦晓雯看走眼忍痛割爱观看两场季后赛,一支拥有四名外援的首钢球队对阵一名外援的吉林男篮,且多赛季打季后赛的首钢男篮经验丰富,没想到搬起石头砸自己意大利取代伊朗进世界杯?因凡蒂诺回应请认真点直播吧4月5日讯此前在接受采访时,国际足联主席因凡蒂诺被问到了意大利是否有可能取代伊朗参加2022年的卡塔尔世界杯,对此,他给出的回复是请认真点。意大利是否可能取代伊朗参加世界杯?真相大白!CBA公布最新报告,首钢获利多拿2分,02横扫技不如人北京首钢被吉林队20横扫淘汰,已经过去了24小时,比赛结束的第二天,CBA公司也很快公布了这场比赛的最后两分钟的裁判报告,还原了比赛最后决胜阶段裁判吹罚情况。让球迷感到意外的是,这
开园了!淮北新地标淮北君今天给你们推荐一个新选择相湖公园来了相湖位于烈山镇洪庄村北侧西临濉溪老濉河,北接杨庄矿是构建淮北城市风貌特色打造中心湖带景观廊道的重要节点据了解,相湖原由周边杨庄矿等煤矿采煤马尔马拉海世界上最小的海马尔马拉海东西长270km,南北宽约70km,面积约为1。1万k,只相当于我国4。5个太湖那么大,比北京市的面积略小,是世界上最小的海。马尔马拉海地理置马尔马拉海海岸陡峭,平均深度韩家窝美变金银窝来源淄博日报淄博新闻网记者孙春晓通讯员伊滢浩美在家庭示范街美学小巷精品民宿竹林荷塘餐饮采摘党校大讲堂村民幸福的笑容初秋时节,周村区南郊镇韩家窝村处处弥漫着美的气息。在这里,庭院美3森林公园南门湖顶山观景台古道森林公园从森林公园到叶洋村,有狠多狠多狠多狠多种的走法,近年新开的石阶道是最最最最简单的走法。从81水库北边(植物园大门对面)的林业科学研究院旁边有个小广场是它的入口,然后1路蜿蜒向上,终1968年,从西宁出发,我们这群新兵踏上了进藏路头条创作挑战赛我的高原军旅生活张登科点击进入15节点击进入6坐着军列进藏7离开西宁,向西藏进发终于,我们开始坐车进藏了。拉兵的汽车团的汽车全是从意大利进口的大意发,又笨又大,烧的是邕江北岸公园美丽异木棉盛放,许你一树繁花的粉色浪漫邕江边一棵美丽异木棉粉色花朵盛放,与青山绿水构成一道独特的秋景。秋日的周末天气晴好。早晨6时许,在南宁市荔滨大道附近的邕江北岸公园一棵美丽异木棉树下,已有人们在拍照打卡。随着太阳升经络一通,百病无踪,4个中成药,祛风湿,通经络,除一身疼痛大家好,我是赵医生,经络一通,疼痛无踪,4个中成药,可祛除风湿,温散里寒,补肝强肾壮筋骨,帮我们除去一身疼痛,快来看看吧!生活中经常有这样的人,总感觉肩膀疼,脖子疼,全身上下肌肉,孕期五大磨人症状,孕妈妈应该如何缓解?这些方法要收藏孕妈妈们在怀孕期间,会感受到各种各样磨人的症状,针对这些不适的表现,孕妈妈们要学会尽可能用温和的方法去缓解,这样对于自己以及肚子里的胎宝宝都更有好处。孕期五大磨人症状,孕妈妈应该如改变虚弱体质需要借助的几个办法一虚弱根源导致虚弱体质的根源,概括起来就是三个根本原因一是先天不足,比如早产多胞胎母体营养供应不足等,这是天生的无法改变的!二是后天损耗太多(支出太多),导致脾胃吸收的水谷精微不够巴中市经信局退休支部开展永远跟党走喜迎二十大主题党日活动为进一步激励广大党员的责任感使命感和荣誉感,10月13日,在党的二十大即将召开之际,巴中市经信局机关党委组织退休支部党员赴南江县赤溪镇西厢村开展永远跟党走喜迎二十大主题党日活动。活12年前,宁坐宝马哭,不坐单车笑的马诺,她如愿以偿了吗?我宁愿坐在宝马上哭,也不愿坐在单车上笑。可能很多人不知道,这句网络流行语出自12年前某档相亲节目的一个女嘉宾之口。这位女嘉宾的名字叫马诺。因为这句话太过偏激和现实,一夜之间她就成了