ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Nacos报Connection refused?从8848到9848端口排查全解析

Nacos报Connection refused?从8848到9848端口排查全解析 说实话第一次遇到 Nacos 报Connection refused的时候我一度以为服务没起来。日志里明明写着Nacos started successfully控制台也打印了一堆启动信息一步都没少但客户端连接时却抛出java.net.ConnectException: Connection refused: connect控制台页面也打不开这就很让人抓狂。这个问题在 Nacos 的日常使用里出现频率相当高而且往往不是单一原因造成的。它可能是网络层被拦截可能是服务只监听了本机回环地址也可能是 2.x 版本新增的 gRPC 端口没暴露甚至是你配置的数据库连不上导致服务“假启动”。这篇文章我会按照实际排查的顺序来写从最基础的“确认到底是谁在拒绝”到单机部署、容器化部署、客户端初始化失败等场景逐一拆开。如果你是第一次部署 Nacos或者刚把 Nacos 从 1.x 升到 2.x再或者把 Nacos 扔进 Docker、Rancher、K8s 之后发现外部访问不了这篇文章应该能帮你节省不少时间。1. 先定位Connection refused 到底发生在哪一层很多人一看到Connection refused就默认是 Nacos 没启动成功其实这个错误信息只能说明“客户端尝试建立 TCP 连接时被对端拒绝了”。它至少能拆成两种情况一种是目标主机的目标端口根本没有进程在监听内核直接回了 RST也就是整个连接被“踢”回来另一种是目标端口即使有服务在监听但监听地址绑定的是127.0.0.1导致外部 IP 的访问请求被拒绝。还有一种容易被忽略的情况就是客户端连接 8848 成功了但后续真正用来做服务发现和配置推送的 gRPC 长连接端口 9848 连不上。日志里表现出的还是Connection refused但如果你只检查 8848 端口会发现一切正常排查方向就会跑偏。1.1 快速区分只有 8848 通连接还是被拒先做最基础的一步在 Nacos 所在的机器上直接请求它的健康检查接口。curl -X GET http://127.0.0.1:8848/nacos/v1/console/health/readiness如果返回{status:UP}说明服务本身的 Web 端口是活着的。这时候再从另一台机器执行同样的请求如果失败那就不是“服务没起来”而是“服务没被外部访问到”。这一步能立刻把问题缩小一大半。然后看端口监听情况。在 Linux 上用这个命令ss -lntp | grep 8848注意看Local Address:Port那一列。如果显示的是0.0.0.0:8848或*:8848说明服务监听的是所有网卡网络问题更多出在防火墙、安全组或容器端口映射上。如果显示的是127.0.0.1:8848那就是典型的“本机能访问、外面访问不了”问题出在 Nacos 的监听地址配置上后面我会专门讲。1.2 别忽略 2.x 的 gRPC 端口88481000 这条隐线Nacos 2.x 之后官方把客户端通信从原来的 HTTP 长轮询改成了 gRPC这是为了提升性能和数据推送的实时性。改造之后Nacos 实际上会监听三个端口端口用途是否必须对外暴露8848HTTP 主端口控制台和 OpenAPI 用是9848客户端 gRPC 端口服务注册、订阅、配置推送都走这里是9849服务端之间的 gRPC 通信端口集群模式使用集群部署时需要9848 和 9849 不是你在配置文件里手动指定的而是根据 8848 端口自动计算出来的规则就是“主端口 1000”和“主端口 1001”。很多人在本地单机测试时没问题因为本机所有端口都能直接访问一旦放到服务器、容器或者云环境里只放行了 8848结果就变成“Nacos 控制台能打开但服务注册不上客户端一直报 Connection refused”。这个坑在 Docker 和 K8s 里特别常见。因为你在宿主机上映射端口时默认只会想到把 8848 映射出去没人会意识到还要把 9848 一起映射。更隐蔽的是如果你把 8848 映射成了别的端口比如-p 18848:8848那客户端甚至会去连接18848100019848这个端口映射关系又对不上了。1.3 三条命令定位问题我一般按照下面的顺序做快速定位# 第一步本机通不通 curl -X GET http://127.0.0.1:8848/nacos/v1/console/health/readiness # 第二步本机三个端口是否都在监听 ss -lntp | grep -E 8848|9848|9849 # 第三步从客户端机器测试端口连通性 telnet 目标IP 8848 telnet 目标IP 9848如果本机三个端口都在监听说明服务那边基本没问题。接着去客户端机器上挨个测端口8848 通但 9848 不通那问题就出在网络的中间环节比如防火墙、安全组规则、容器端口映射或者 K8s 的 Service 配置。这比一上来就翻 Nacos 日志分析要高效得多。2. 单机部署最常踩的坑绑定地址、启动模式、防火墙如果你不是用容器部署而是在 Linux 服务器上直接解压 Nacos 安装包那遇到Connection refused大概率是下面三个原因之一。我按照出现频率排个序。2.1 监听地址不对服务“成功”了个寂寞Nacos 的启动脚本默认会尝试获取本机 IP如果你在application.properties里手动设置了nacos.inetutils.ip-address这个值会影响服务注册时对外宣告的 IP但更关键的是它也会影响服务实际绑定的地址。有些人为了让 Nacos 在集群模式下稳定注册把这个 IP 写成了127.0.0.1结果就是本机能访问其他机器全部 Connection refused。还有一个常见场景是服务器上有多个网卡比如有内网 IP、外网 IP、Docker 虚拟网卡。Nacos 自动选择 IP 的时候可能选到了一个不通的地址客户端连接时自然就失败了。解决办法是在conf/application.properties里显式指定对外提供的 IPnacos.inetutils.ip-address10.0.0.10如果不是设置错了 IP而是服务只监听了127.0.0.1那也可以检查conf/application.properties里有没有server.address这样的配置。正常情况下 Nacos 默认监听0.0.0.0不需要额外配置如果你在启动脚本或环境变量里强行加过地址绑定参数就很容易出现“只有本机能访问”的现象。2.2 standalone 和 cluster把启动模式搞清楚Nacos 默认的启动模式其实是集群模式虽然它也能起来但如果没有正确配置conf/cluster.conf单节点环境下会进入一种“伪健康”状态端口在监听但集群选主一直不成功控制台打开后你会发现集群节点列表是空的服务注册也可能不成功。正确的单机启动方式是在脚本后面加参数bin/startup.sh -m standaloneWindows 环境下对应的是startup.cmd -m standalone如果你是直接用java -jar的方式启动也要记得加上-Dnacos.standalonetrue否则它会按照集群模式去初始化。有一次我排查一个现场环境服务明明起来了但客户端怎么都连不上最后发现就是启动脚本里漏了-m standalone导致集群选举一直在重试。所以看到Connection refused别急着去查防火墙先确认你的启动参数到底对不对。还要留意 Linux 服务器上可能残留了旧版本的 Nacos 进程。如果之前用 1.x 启动过后来又用 2.x 启动两个进程可能同时抢 8848 端口但后启动的那个因为端口占用而实际失败。这时候看logs/start.out是“成功”还是“端口占用”一眼就能判断。2.3 防火墙、安全组和端口占用怎么查如果确认服务监听地址没有问题那就要查防火墙。CentOS 7 及以上版本默认使用 firewalld先看当前开放了哪些端口firewall-cmd --list-ports如果没有 8848、9848、9849执行firewall-cmd --permanent --add-port8848/tcp firewall-cmd --permanent --add-port9848/tcp firewall-cmd --permanent --add-port9849/tcp firewall-cmd --reloadUbuntu 系统上默认是 ufw命令类似用ufw allow 8848/tcp这样去放行。除了服务器本机防火墙云厂商的安全组也是个高频坑。很多人在阿里云、腾讯云上搭建 Nacos服务器防火墙全部关了还是访问不了一查安全组规则发现只放行了 22 端口和常见的 80、4438848 完全被挡在外面。这时候去云控制台把端口加到安全组规则里就行。端口占用问题也不难查。比如 8848 被其他程序占了Nacos 启动日志会报BindException但如果你没看日志只看到进程在就会误以为服务正常。用lsof -i:8848或ss -lntp | grep 8848能看到占用进程的 PID然后ps -ef | grep PID确认是不是 Nacos。这一点虽然基础但我见过好几次因为旧实例没停干净导致的排查事故。3. Docker 和 Rancher 部署时外部访问失败的处理现在很多同学喜欢用 Docker 直接跑 Nacos尤其会在 Rancher 这类容器管理平台上部署。容器化带来的问题是端口映射、容器网络模式、环境变量都会成为排查重点。3.1 容器里正常、容器外失败先别急着怪镜像先做一个实验进入容器内部执行健康检查接口。docker exec -it nacos-container bash curl -X GET http://127.0.0.1:8848/nacos/v1/console/health/readiness如果在容器内返回UP而宿主机上访问失败那大概率是端口映射的问题。最简单的 Docker 启动命令应该是这样的docker run -d \ --name nacos \ -p 8848:8848 \ -p 9848:9848 \ -p 9849:9849 \ -e MODEstandalone \ nacos/nacos-server:v2.3.2很多人只写了-p 8848:8848这样暴露出来的端口是不完整的。如果你的 Nacos 是 2.x客户端连不上、服务注册失败极大概率就是少了-p 9848:9848。还有一种情况是容器内部默认使用 bridge 网络Nacos 在容器里读取到的自身 IP 是172.17.0.x这种内网地址。如果在application.properties或环境变量里设置了NACOS_BIND_IP并且把它指定成了某个固定 IP而这个 IP 和宿主机网络对不上那即使端口映射正确也可能出现隧道“错位”的问题。这时候把环境变量改成NACOS_BIND_IP0.0.0.0或者在启动脚本里不指定具体 IP让 Nacos 自己去选反而更简单。3.2 gRPC 端口映射2.x 容器化最容易漏的一环容器场景下的 gRPC 端口问题比裸机更隐蔽。因为容器的端口映射是“一对一”的如果你把 8848 映射到宿主机的 8848那 9848 也必须在宿主机上找到对应的端口否则客户端的 gRPC 连接就会失败。我在前面的命令里已经写了三组端口映射注意这里有个细节Nacos 客户端在连接时会根据你配置的server-addr端口自动加 1000 去连接 gRPC 端口。也就是说如果你在客户端配置的是110.0.0.5:8848那它会去连110.0.0.5:9848。如果你在宿主机上把 Nacos 的 8848 映射成了别的端口比如-p 18848:8848那客户端就会去连接18848100019848而这个端口你大概率没有映射于是又变成 Connection refused。所以容器化部署 Nacos 时我的建议是尽量保持端口映射比例一致即 8848 映射 8848、9848 映射 9848不要随便修改外部映射端口。如果因为业务需要必须修改外部映射端口请在客户端配置里使用对应的server-addr值并确保 gRPC 端口偏移规则能对上。实际上 Nacos 提供了nacos.server.grpc.port.offset这个配置项来调整偏移量但在容器里调整它会让问题更复杂非必要不建议动。3.3 Rancher/K8s 暴露 Nacos 的正确姿势在 Rancher 上部署 Nacos本质上就是跑 Kubernetes 工作负载。很多人会把 Deployment 创建好端口也填了但在 Rancher 的 Service 规则里只暴露了 8848NodePort 也只映射了 8848结果客户端从集群外部访问时控制台打开正常服务注册却一直超时或者 Connection refused。正确做法是在 Service 里把 8848、9848、9849 三个端口都暴露出来。用 NodePort 模式举个例子apiVersion: v1 kind: Service metadata: name: nacos-server spec: type: NodePort selector: app: nacos ports: - name: http port: 8848 targetPort: 8848 nodePort: 30088 - name: grpc-client port: 9848 targetPort: 9848 nodePort: 30988 - name: grpc-server port: 9849 targetPort: 9849 nodePort: 30989这里要特别提醒如果你的 Service 用了 ClusterIP 类型那只有集群内部可以访问。如果你在 Rancher 上创建了一个工作负载Rancher 只给你生成一个 ClusterIP 的 Service那在集群外访问时直接就会 Connection refused。正确做法是把 Service 改成 NodePort 或 LoadBalancer然后在客户端配置里填写“节点 IP 对应 NodePort”而不是“ClusterIP 8848”。在 K8s 里还有一个隐藏问题Pod 重启后 IP 会变化。如果你在客户端写的是 Pod IP那 Pod 一旦重建就会失效。更稳妥的方式是用 Service 的 DNS 名称或者在客户端配置里使用 LoadBalancer 提供的稳定 IP。如果你的 Nacos 需要关联 MySQL那还要给 MySQL 也单独建 Service同时注意数据库地址不要写成localhost因为容器里的 localhost 指的是容器本身不是宿主机上的 MySQL。4. 客户端初始化失败与配置中心相关的隐藏原因有些时候 Nacos 服务端确实没问题端口也通了但客户端启动还是报 Connection refused 或者初始化失败。这种问题往往不在 Nacos 本身而在你的客户端配置或网络代理上。4.1 Nacos 连接的是数据源别把数据库故障当成端口故障如果你的 Nacos 配置了外置 MySQL 数据库但数据库地址连接不上或者数据库账号密码错误Nacos 启动时虽然会打印一堆错误但也可能会先出现一段时间“假活”状态。这种场景下外部访问看起来是端口连不上实际上的根因是 Nacos 的存储层初始化失败了服务并没有真正对外提供能力。排查方式很简单看logs/start.out或logs/nacos.log里有没有数据库相关的异常。比如Cannot create PoolableConnectionFactory、Communications link failure这类报错那就要去检查 MySQL 是否启动、账号密码是否正确、jdbc:mysql://地址能否连通。注意Nacos 在启动时会自动建表所以数据库账号需要有建表权限。如果你给了个只读账号启动过程一样会报错控制台也无法正常使用。4.2 “初始化失败请检查 url、网络和代理设置”到底是谁的问题这个报错我在热搜词里也看到了“的初始化失败 请检查 url、网络和代理设置。错误消息: cannot download https://start.aliyun.com/: connection refused”。很多人看到这个会以为 Nacos 出问题了但其实这个错误是 IDE 在创建 Spring Boot 项目时从阿里云的初始化服务下载模板失败导致的和 Nacos 本身并没有直接关系。如果你遇到这种“初始化失败”核心要检查的是IDE 的代理设置、本机到start.aliyun.com的网络连通性。如果你的网络环境访问不到这个域名可以换成 Spring 官方提供的https://start.spring.io/来创建项目。这个错误只是项目脚手架下载问题不影响 Nacos 后续的使用注意不要把它和 Nacos 部署问题混在一起排查。4.3 spring.config.import 缺失导致配置中心连接异常另一个很典型的问题是 Spring Cloud 2020 之后版本的变化。以前我们在bootstrap.yml里配置 Nacos 配置中心地址就能自动加载但新版本 Spring Cloud 默认不再启用 bootstrap需要显式配置spring.config.import否则启动时就会看到类似no spring.config.import property has been defined的报错。这种情况下Nacos 服务本身是正常的但项目启动时可能因为找不到 Nacos 配置或者根本没有尝试连接配置中心导致后续注册中心的连接也异常。解决方式是在application.yml或bootstrap.yml里正确加入spring: config: import: nacos:config-data?server-addr127.0.0.1:8848 cloud: nacos: discovery: server-addr: 127.0.0.1:8848 config: server-addr: 127.0.0.1:8848 file-extension: yaml如果你还是在用bootstrap.yml需要额外引入spring-cloud-starter-bootstrap依赖。这个问题和端口无关但排查起来很迷惑因为你看 Nacos 控制台一切正常客户端却始终起不来或者报配置加载失败。4.4 顺带回答Nacos 能接 DB2、达梦吗热搜里也有人问“Nacos 支持 DB2 吗”“Nacos 2.2.3 达梦”。简单说Nacos 官方原生支持的数据库是 MySQL 和内置的 Derby达梦数据库需要你通过 Nacos 的 datasource 插件机制去适配。DB2 官方也没有直接提供需要自己写 datasource 插件或者改连接驱动。如果你在配置里强行把数据库类型改成 DB2 或达梦而没有对应的驱动和方言支持启动时会报Connection refused或者 SQL 执行异常。这种情况本质是数据源初始化失败不是端口问题。如果一定要用国产数据库建议去查 Nacos 官方仓库里对应的 datasource 插件目前官方社区对达梦等数据库的适配资料也在逐步完善但不要指望改一个 URL 就能直接跑通。5. 一张速查表 一套排查模板排查Connection refused的时候最忌讳的就是“头痛医头”。我整理了一张速查表直接对照症状找原因能省不少时间。现象可能原因先查什么本机 curl 8848 正常外部访问失败监听地址绑定了 127.0.0.1ss -lntp看监听地址本机 curl 正常外部访问超时或被拒防火墙/安全组/端口映射telnet客户端端口连通性控制台能打开服务注册失败2.x gRPC 端口 9848 未开放测试 9848 连通性Nacos 进程在但端口没监听启动模式异常或端口被占用看logs/start.out容器内正常宿主机访问失败端口映射缺少 gRPC 端口docker ps看映射客户端报 no spring.config.importSpring Cloud 版本配置问题检查 bootstrap/application 配置Nacos 启动报数据库错误数据源连接异常检查 MySQL 账号和 URL5.2 可复用的排查顺序我平时处理这类问题的标准化步骤是这样的第一步先看 Nacos 自身是否真的可用。在 Nacos 所在机器上执行curl http://127.0.0.1:8848/nacos/v1/console/health/readiness如果返回不是UP那就先解决启动问题。第二步查端口监听情况。ss -lntp | grep -E 8848|9848|9849确认三个端口都在监听。这一步基本能排除“服务没起来”和“端口被占用”的问题。第三步从客户端机器测试端口连通性。telnet8848 和 9848看哪个通哪个不通。这一步能快速分辨是网络问题还是端口映射问题。第四步如果前面都正常再去翻客户端日志。重点看报错的时间点是否伴随其他异常比如配置加载失败、数据库连接失败。很多问题不是 Nacos 拒绝你而是你的应用在发起连接之前就自己挂了。第五步也是最容易被忽略的确认客户端配置的server-addr和 Nacos 实际监听地址是否匹配。比如 Nacos 在服务器 A 上监听内网 IP但你客户端配置的是公网 IP这就要看网络路由和安全组是否放行。按照这个顺序走下来大多数Connection refused都能在十分钟内定位。说白了很多坑不是 Nacos 本身的问题而是环境、版本、端口映射这些“周边设施”没理顺。尤其是 2.x 之后加了 gRPC 端口排查思路必须从“只看 8848”升级成“8848、9848、9849 三个端口一起看”。最后再分享一个小技巧如果你在 K8s 或 Rancher 里部署 Nacos建议把 ReadinessProbe 配置成访问健康检查接口这样 Pod 的状态能真实反映 Nacos 是否就绪不会出现“容器起来了但服务不可用”的假象。我在实际项目里用这个方式排查过几次效果很直接至少不会让问题藏在 Pod 状态背后。
返回列表