java应用无法获取nacos导入的yml文件配置

我用的nacos服务端是2.2.0版本,代码springboot版本是2.7.8版本。部署环境是二次开发过的k8s
代码连接nacos服务端是这样写的:

记录一个卡了几天的问题——应用程序无法获取达梦数据库版的nacos2.2.0版本导入的yml配置_数据库

在nacos服务端是这样写的:

记录一个卡了几天的问题——应用程序无法获取达梦数据库版的nacos2.2.0版本导入的yml配置_dockers_02

成功案例:命名空间名称和ID都是一样的,group是默认的,已经在本地和生产环境都成功获取到配置了的,都是相同版本。

但是在别的环境部署,就无法获取到配置了,以下是无法获取配置的相关错误日志:

记录一个卡了几天的问题——应用程序无法获取达梦数据库版的nacos2.2.0版本导入的yml配置_达梦数据库_03

记录一个卡了几天的问题——应用程序无法获取达梦数据库版的nacos2.2.0版本导入的yml配置_nacos_04

无论是成功或者失败的案例都是统一部署在k8s上的,docker和本地源码部署也部署过,nacos和业务应用都是部署在同一个命名空间,使用curl命令能访问我上传到nacos的配置:

记录一个卡了几天的问题——应用程序无法获取达梦数据库版的nacos2.2.0版本导入的yml配置_nacos_05

但是应用无法自动获取

————————      ——以下是问题解决思路与最终解决办——————————————

其实一开始都是按照常规的做法:

1、检查程序连接nacos的IP或者域名加端口、命名空间、加载的文件名以及账号密码之类的东西。

2、还有的就是在检查一下nacos控制台,检查命名空间名称、ID、以及文件名之类的。

3、在应用中使用curl工具通过api可以访问并获取nacos的配置,因此可以排除网络问题。
4、在服务器上使用同一个nacos达梦版源码包部署nacos,应用程序能正常获取配置。
5、在服务器上使用同一个dockerfile,同一个nacos达梦版源码包(只修改了IP)制作镜像,起了一个nacos容器,然后使用应用程序镜像也起了一个应用容器。nacos导入相关配置后,启动应用程序镜像,能正常连接nacos并获取配置。

通过以上常规做法还是无法定位问题所在。

后面想想,问了群里某个大佬,无意间的一句话被他点播了一下,nacos2以上版本使用了4个端口,可是我单机部署应该用不了那么多端口,那时候我只暴露了一个8848,之前我在k8s上集群部署过才需要这么多端口:其实我是缺了9848端口

  • 8848:HTTP 端口,用于 API 和 Web 控制台。
  • 7848:集群节点间的 Raft 协议通信端口。
  • 9848:客户端与服务器的 gRPC 通信端口。
  • 9849:集群节点间的 gRPC 通信端口。

但是那时候我就在想,我用docker部署nacos的时候也是只暴露了一个端口,为啥子应用程序也能正常获取配置?然后我就不想那么多,死马当活马医,继续发布了剩余端口,我重启服务,看着没啥变化,也就没有继续在管,正当我还以为再次失败的时候,过了十几分钟,刷新了nacos服务列表,突然看到有个应用成功注册了。我就明白果然是端口的问题。

现场提供的环境是k8s集群,我想着只部署一个单机版就够了,也就之暴露了8848端口,我看程序上也没使用其他端口,就没有继续暴露剩下几个端口。

而使用docker部署和源码包部署,之所以也能成功让程序获取到配置,请看以下gpt给的答案,我认为很有道理,也许就是这个原因

1. Nacos 2.x 的通信机制
Nacos 2.x 引入了 gRPC 作为客户端与服务器之间的通信协议,而不仅仅是 HTTP。具体来说:

8848 端口:仅用于 HTTP API 和 Web 控制台。

9848 端口:用于客户端与服务器之间的 gRPC 通信(这是 Nacos 2.x 的默认行为)。

在 Nacos 2.x 中,客户端(你的应用程序)会首先通过 8848 端口 连接到 Nacos 服务器,但随后 Nacos 服务器会返回一个 gRPC 地址(通常是 9848 端口),客户端会尝试通过 gRPC 进行后续的配置获取和监听。

2. Docker 和 Kubernetes 的网络环境差异
Docker 环境:

如果你在 Docker 中只暴露了 8848 端口,但容器内部的所有端口(包括 7848、9848、9849)仍然是通的。

客户端和 Nacos 服务器在同一个网络环境中,客户端可以直接通过容器内部的 gRPC 端口(9848)与 Nacos 通信。

Kubernetes 环境:

Kubernetes 的网络模型更加严格,Pod 之间的通信需要通过 Service 暴露的端口进行。

如果你只暴露了 8848 端口,客户端无法访问 Nacos 的 gRPC 端口(9848),因为 Kubernetes 的网络策略会阻止这种通信。

因此,客户端无法通过 gRPC 获取配置,导致配置获取失败。

3. 为什么程序只引用了 8848 端口,但仍然需要 gRPC 端口?
虽然你的程序配置中只写了 8848 端口,但 Nacos 2.x 的客户端 SDK 在启动时会做以下事情:

通过 8848 端口(HTTP)连接到 Nacos 服务器。

从 Nacos 服务器获取 gRPC 地址(通常是 9848 端口)。

尝试通过 gRPC 端口进行后续的配置获取和监听。

如果 gRPC 端口不可达,客户端会无法获取配置。

总之就是对nacos不熟悉惹的祸,折磨了了好几天,也多亏了大佬的点播。