SpringCloud及Nacos服务注册IP选择问题解决方法

 更新时间:2024年01月09日 11:25:38   作者:算了吧,你不配  
这篇文章主要介绍了SpringCloud及Nacos服务注册IP选择问题,为什么注册的IP和真实IP不符合呢,原因是Nacos客户端在注册服务时会从机器网卡中选择一个IP来注册,所以,当注册了的是非真实IP后,另一台机器调用时是不可能调通的,知道问题原因就是解决方法,一起看看吧

一、SpringCloud以及Nacos服务注册IP选择问题

场景:

微服务部署后,需要相互调用,其中服务A调用服务B时发现无法调用。其中服务注册和发现以及配置中心使用Nacos

分析:

检查了多遍代码后,没有发现调用方式有问题,所以只能是网络问题。通过postman直接调用服务B,发现可以调通,但是使用服务A不行,于是检查服务A在注册中心注册的IP,发现和并不是服务B启动机器的IP。这就是问题所在了。

为什么注册的IP和真实IP不符合呢?原因是Nacos客户端在注册服务时会从机器网卡中选择一个IP来注册,当机器存在多个网卡(例如存在虚拟网卡)时,所选则的IP可能不是真是的物理机的IP,所以,当注册了的是非真实IP后,另一台机器调用时是不可能调通的。

解决:

知道问题后,就要解决,查了一下SpringCloud的官方文档,发现有一项配置如下:

Sometimes, it is useful to ignore certain named network interfaces so that they can be excluded from Service Discovery registration (for example, when running in a Docker container). A list of regular expressions can be set to cause the desired network interfaces to be ignored.
You can also force the use of only specified network addresses by using a list of regular expressions.

spring:
  cloud:
	inetutils:
	  preferredNetworks:
		- 192.168
		- 10.0

该项配置用于指定首选IP,当有多个网卡时,指定该IP地址后(支持正则),客户端在选择IP时就会选择符合preferredNetworks配置的IP地址进行注册。

同样的,Nacos也可以配置自己的首选IP以及网卡选择:

spring.cloud.nacos.discovery.ip:
spring.cloud.nacos.discovery.networkInterface

我们选择其中一个配置就可以,都能达到相同的效果。

扩展:

虽然问题解决了,但是还是要更深入的了解一下这个IP选择的逻辑。翻了一通源码发现,其大致逻辑如下:

Nacos首先检查有没有ip及networkInterface配置,如果有则使用配置的IP,否则检查networkInterface,并获取IP,如果两者都为空,则使用inetUtils.findFirstNonLoopbackHostInfo().getIpAddress()来获取IP:

而findFirstNonLoopbackHostInfo()的部分逻辑如下:

它最终会返回一个匹配的IPV4地址,并且排除本机回环网络(127.0.0.0-127.255.255.255),并且匹配是否是首选网络(如果配置了preferredNetworks)。

二、注册为指定IP和端口

如果选择固定Ip注册可以配置

spring.cloud.nacos.discovery.ip = 192.168.0.118
spring.cloud.nacos.discovery.port = 9000

如果选择固定网卡配置项

spring.cloud.nacos.discovery.networkInterface = eth0

如果想更丰富的选择,可以使用spring cloud 的工具 InetUtils进行配置

具体说明可以自行检索: https://github.com/spring-cloud/spring-cloud-commons/blob/master/docs/src/main/asciidoc/spring-cloud-commons.adoc

spring.cloud.inetutils.default-hostname
spring.cloud.inetutils.default-ip-address
spring.cloud.inetutils.ignored-interfaces[0]=eth0 # 忽略网卡,eth0
spring.cloud.inetutils.ignored-interfaces=eth.* # 忽略网卡,eth.*,正则表达式
spring.cloud.inetutils.preferred-networks=10.34.12 # 选择符合前缀的IP作为服务注册IP
spring.cloud.inetutils.timeout-seconds
spring.cloud.inetutils.use-only-site-local-interfaces

更多配置

spring.cloud.nacos.discovery.server-addr #Nacos Server 启动监听的ip地址和端口
spring.cloud.nacos.discovery.service #给当前的服务命名
spring.cloud.nacos.discovery.weight #取值范围 1 到 100,数值越大,权重越大
spring.cloud.nacos.discovery.network-interface #当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址
spring.cloud.nacos.discovery.ip # 优先级最高
spring.cloud.nacos.discovery.port # 默认情况下不用配置,会自动探测
spring.cloud.nacos.discovery.namespace # 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 spring.cloud.nacos.discovery.access-key # 当要上阿里云时,阿里云上面的一个云账号名
spring.cloud.nacos.discovery.secret-key # 当要上阿里云时,阿里云上面的一个云账号密码
spring.cloud.nacos.discovery.metadata #使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息
spring.cloud.nacos.discovery.log-name # 日志文件名
spring.cloud.nacos.discovery.enpoint # 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
ribbon.nacos.enabled # 是否集成Ribbon 默认为true

三、通过内网ip注册为指定外网ip

Nacos注册中心是: https://github.com/alibaba/nacos

各个服务通过Nacos客户端将服务信息注册到Nacos上,当Nacos服务注册的IP默认选择出问题时,可以通过查阅对应的客户端文档,来选择配置不同的IP。

大多公司服务器环境会有两套ip,一套是对内网,一套是对外网。即同一台服务器,有对应两个ip(例:10.0.0.1,100.0.0.1)。

在使用nacos做为注册中心,由于内网环境的因素,A服务注册上去的ip可能是100.0.0.1,B服务注册上去的ip可能是10.0.0.2,经验证10之间调用互通,100之间也互通。但10调用100不同,或者反之也不行。

解决方案:
配置文件加如下配置:

nacos-ip-100.0.0.1 = 10.0.0.1
spring.cloud.nacos.discovery.ip = ${nacos-ip-${spring.cloud.client.ip-address}}

四、Nacos服务注册地址为内网IP的解决办法

问题

最近在使用Spring Cloud Alibaba这一套微服务解决方案,但是在服务注册的时候,网关死活找不到微服务地址,自己的微服务通过网关怎么也访问不到。

查找原因

仔细一查才发现,网关去访问了一个莫名其妙的IP地址,
去Nacos服务详情去看,果然,我的微服务注册到Nacos的IP地址上也是这个地址,
然后我去我电脑查找这个IP地址,还真有这么一个地址,那么问题来了,Nacos为什么会随意找个本机IP地址然后注册上去?

Nacos服务注册的IP

Nacos注册中心是: https://github.com/alibaba/nacos
各个服务通过Nacos客户端将服务信息注册到Nacos上
当Nacos服务注册的IP默认选择出问题时,可以通过查阅对应的客户端文档,来选择配置不同的网卡或者IP
参考org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties的配置

解决办法

例如,使用了Spring cloud alibaba(官方文档)作为Nacos客户端,
服务默认获取了内网IP 192.168.1.21,
可以通过配置spring.cloud.inetutils.preferred-networks=10.34.12,使服务获取内网中前缀为10.34.12的IP

如何配置

# 如果选择固定Ip注册可以配置
spring.cloud.nacos.discovery.ip = 10.2.11.11
spring.cloud.nacos.discovery.port = 9090
# 如果选择固定网卡配置项
spring.cloud.nacos.discovery.networkInterface = eth0
# 如果想更丰富的选择,可以使用spring cloud 的工具 InetUtils进行配置
# 具体说明可以自行检索: https://github.com/spring-cloud/spring-cloud-commons/blob/master/docs/src/main/asciidoc/spring-cloud-commons.adoc
spring.cloud.inetutils.default-hostname
spring.cloud.inetutils.default-ip-address
spring.cloud.inetutils.ignored-interfaces[0]=eth0   # 忽略网卡,eth0
spring.cloud.inetutils.ignored-interfaces=eth.*     # 忽略网卡,eth.*,正则表达式
spring.cloud.inetutils.preferred-networks=10.34.12  # 选择符合前缀的IP作为服务注册IP
spring.cloud.inetutils.timeout-seconds
spring.cloud.inetutils.use-only-site-local-interfaces

更多配置

spring.cloud.nacos.discovery.server-addr  #Nacos Server 启动监听的ip地址和端口
spring.cloud.nacos.discovery.service  #给当前的服务命名
spring.cloud.nacos.discovery.weight  #取值范围 1 到 100,数值越大,权重越大
spring.cloud.nacos.discovery.network-interface #当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址
spring.cloud.nacos.discovery.ip  # 优先级最高
spring.cloud.nacos.discovery.port  # 默认情况下不用配置,会自动探测
spring.cloud.nacos.discovery.namespace # 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
spring.cloud.nacos.discovery.access-key  # 当要上阿里云时,阿里云上面的一个云账号名
spring.cloud.nacos.discovery.secret-key # 当要上阿里云时,阿里云上面的一个云账号密码
spring.cloud.nacos.discovery.metadata    #使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息
spring.cloud.nacos.discovery.log-name   # 日志文件名
spring.cloud.nacos.discovery.enpoint   # 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
ribbon.nacos.enabled  # 是否集成Ribbon 默认为true

五、较合理的实现方式

1.使用docker进行部署

  • 项目打包的时候指定映射后的注册IP和端口或者ip前缀
  • 打包进镜像之后运行容器,设置上方指定的端口映射
  • 这样也能指定局域网的IP也可以通过docker将相关端口进行映射出来

问题,假如需要映射到公网IP?

2.也可以通过网关进行整改,所有服务都走网关,

  • 只需要将网关部署到连接内网服务的网卡上面,将网关的端口进行映射出去供外部调用
  • 问题,服务间的调用需要保证注册网络是统一网络

3.通过自定义主机域名,或者本地dns服务,

  • 给每个服务指定域名
  • 服务注册时候需要将域名进行者注册上去,

问题:可能会更麻烦但是对于网络较为复杂的情况会改善一点劳动量 

到此这篇关于SpringCloud以及Nacos服务注册IP选择问题的文章就介绍到这了,更多相关SpringCloud Nacos服务注册内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Redis原子计数器incr,防止并发请求操作

    Redis原子计数器incr,防止并发请求操作

    这篇文章主要介绍了Redis原子计数器incr,防止并发请求操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • SpringMVC的工程搭建步骤实现

    SpringMVC的工程搭建步骤实现

    这篇文章主要介绍了SpringMVC的工程搭建步骤实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Java LocalDateTime常用操作方法

    Java LocalDateTime常用操作方法

    这篇文章主要介绍了Java LocalDateTime实用方法,Java8提供了新的时间接口LocalDateTime,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • 浅谈Java设计模式之原型模式知识总结

    浅谈Java设计模式之原型模式知识总结

    Java原型模式主要用于创建重复的对象,同时又能保证性能,这篇文章就带大家仔细了解一下原型模式的知识,对正在学习java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • Mybatis Trim标签用法简单介绍

    Mybatis Trim标签用法简单介绍

    这篇文章主要介绍了Mybatis Trim标签用法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-05-05
  • Java 实现滑动时间窗口限流算法的代码

    Java 实现滑动时间窗口限流算法的代码

    这篇文章主要介绍了Java 实现滑动时间窗口限流算法的代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Java中的java.lang.reflect.Type简介

    Java中的java.lang.reflect.Type简介

    在 Java 中,java.lang.reflect.Type 是一个接口,代表所有类型的通用超类型,它包括原始类型、参数化类型、数组类型、类型变量和基本类型,本文给大家讲解Java中的java.lang.reflect.Type是什么,需要的朋友可以参考下
    2024-06-06
  • RocketMQ消息积压原因及处理方法

    RocketMQ消息积压原因及处理方法

    RocketMQ是一种可靠的、可扩展的消息中间件,广泛应用于分布式系统中的消息通信,然而,在高并发的场景下,由于消息产生速度超过消费速度,可能会导致消息积压的问题,本文将介绍RocketMQ消息积压的原因和如何处理积压问题
    2023-06-06
  • SpringMVC实战案例RESTFul实现添加功能

    SpringMVC实战案例RESTFul实现添加功能

    这篇文章主要为大家介绍了SpringMVC实战案例RESTFul实现添加功能详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Java源码解析之详解ReentrantLock

    Java源码解析之详解ReentrantLock

    今天给大家带来的是关于Java并发的相关知识,文章围绕着ReentrantLock源码展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06

最新评论