起因:
因考虑以下原因,故以naocs替换eureka
- 统一的服务注册与配置中心:Nacos 提供了统一的服务注册与配置管理功能,可以将服务注册和配置管理集成在一个平台上。这样可以简化系统架构,减少依赖的组件数量。
-
动态配置管理:Nacos 提供了动态配置管理功能,可以实时修改配置信息并通知服务实例,无需重启应用或重新部署。这使得系统的配置更新更加方便和高效。
-
支持多种注册中心模式:Nacos 支持多种注册中心模式,包括基于 DNS 的服务发现和基于 RPC 的服务发现。这使得 Nacos 在不同网络环境和应用场景下更加灵活。
-
社区活跃度和发展趋势:Nacos 是由阿里巴巴开源的项目,在开源社区中得到了广泛的关注和贡献。它具有活跃的社区支持和快速的发展趋势。
项目构成
- 使用docker-compose在单实例上启动的两个v2.2.0版本的nacos容器
- springboot项目引入2.2.0版本的nacos依赖
- nginx代理做两个nacos端口的转发负载
过程
项目报错的日志:
ERROR o.s.boot.SpringApplication.reportFailure(SpringApplication.java:826) - Application run failed
java.lang.reflect.UndeclaredThrowableException: null
at org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:147)
at com.alibaba.cloud.nacos.registry.NacosServiceRegistry.register(NacosServiceRegistry.java:73)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.register(AbstractAutoServiceRegistration.java:239)
at com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration.register(NacosAutoServiceRegistration.java:76)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.start(AbstractAutoServiceRegistration.java:138)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.bind(AbstractAutoServiceRegistration.java:101)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.onApplicationEvent(AbstractAutoServiceRegistration.java:88)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.onApplicationEvent(AbstractAutoServiceRegistration.java:47)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:403)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:360)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:165)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at net.novelcomic.server.author.NcAuthorApplication.main(NcAuthorApplication.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Caused by: com.alibaba.nacos.api.exception.NacosException: failed to req API:/api//nacos/v1/ns/instance after all servers([172.25.151.166:8848]) tried: <html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>Thu Jun 15 09:10:16 CST 2023</div><div>There was an unexpected error (type=Bad Request, status=400).</div><div>receive invalid redirect request from peer 172.19.0.2</div></body></html>
at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:496)
at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:401)
at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:397)
at com.alibaba.nacos.client.naming.net.NamingProxy.registerService(NamingProxy.java:212)
at com.alibaba.nacos.client.naming.NacosNamingService.registerInstance(NacosNamingService.java:207)
at com.alibaba.cloud.nacos.registry.NacosServiceRegistry.register(NacosServiceRegistry.java:64)
... 26 common frames omitted
- 问题就在于访问nacos的 /api//nacos/v1/ns/instance 的接口报错,原因存在以下几点
-
Nacos 注册中心实例配置不正确或无法访问,可以尝试使用
curl
命令或浏览器访问该地址,确认是否能够正常访问。 -
Nacos 注册中心的路径配置有误,检查 Spring 项目中 Nacos 的配置项,确保
server-addr
配置正确指向 Nacos 实例的地址和端口。 -
Nacos 注册中心的版本与您的 Spring 项目不兼容。确保使用的 Nacos 版本与 Spring Cloud 版本兼容。可以尝试升级或降级 Nacos 版本,或查阅相关文档以确认兼容性。
- 2、3两点问题我已确定不会存在问题,问题就在于1
[root@MT01 nc-author-service]# curl http://172.25.151.166:8848/nacos/v1/ns/instance?serviceName=nc-author-service
caused: Param 'ip' is required.
这是在访问 /nacos/v1/ns/instance
接口时,需要提供 ip
参数,是因为该接口用于注册服务实例信息到 Nacos 服务注册中心。ip
参数指定了注册的服务实例的 IP 地址。
但是我用的是新版v2.x版本的nacos。
在旧版本的 Nacos 中(如 v1.x 版本),ip
参数是必需的,因为它用于标识要注册的实例的 IP 地址。如果没有提供 ip
参数,将会出现类似 "Param 'ip' is required." 的错误。
但在较新的版本中(如 v2.x 版本),Nacos 引入了自动获取 IP 地址的功能,即使不提供 ip
参数,也能正确注册实例。Nacos 将根据服务器的网络配置自动获取 IP 地址,并将其用于注册。这样,访问 /nacos/v1/ns/instance
接口时就不再需要手动携带 ip
参数。
这就是问题所在!!!
因为使用docker启动的nacos,故ip为容器内ip,所以注册不上,只需让容器内ip取宿主机的ip即可。
解决方案
-
使用主机名代替 IP 地址:在注册服务实例时,将主机名作为
ip
参数的值,而不是具体的 IP 地址。这样,Nacos 将使用主机名来标识服务实例的网络地址。 -
配置自动获取 IP 地址:有些框架和组件可以自动获取本机的 IP 地址并注册到 Nacos 中,而无需手动指定。例如,Spring Cloud 中的
spring-cloud-starter-alibaba-nacos-discovery
可以通过配置spring.cloud.inetutils.ignored-interfaces
来忽略指定的网络接口,从而自动获取可用的 IP 地址并进行注册。
采用方案一则修改nacos,network_mode: host
与port_bindings
不能同时使用,需去掉ports
version: '3'
services:
nacos-node1:
image: nacos/nacos-server:v2.2.0
container_name: nacos-node1
environment:
- PREFER_HOST_MODE=hostname
- MODE=cluster
- NACOS_SERVERS=nacos-node1:8848,nacos-node2:8848
- JVM_XMS=512m
- JVM_XMX=1024m
- NACOS_SERVER_IP=你的私网ip
restart: always
volumes:
- /data/nacos/conf/application.properties:/home/nacos/conf/application.properties
- /data/nacos/logs/8847:/home/nacos/logs
network_mode: host
nacos-node2:
image: nacos/nacos-server:v2.2.0
container_name: nacos-node2
environment:
- PREFER_HOST_MODE=hostname
- MODE=cluster
- NACOS_SERVERS=nacos-node1:8848,nacos-node2:8848
- JVM_XMS=512m
- JVM_XMX=1024m
- NACOS_SERVER_IP=你的私网ip
restart: always
volumes:
- /data/nacos/conf/application1.properties:/home/nacos/conf/application.properties
- /data/nacos/logs/8849:/home/nacos/logs
network_mode: host