Nacos引擎的命名空间怎么使用 ?
命名空间是基于租户粒度的隔离。命名空间的常用场景之一是不同环境的配置和服务的区分隔离,例如开发环境、测试环境和生产环境的资源隔离等。不同的命名空间下,可以存在相同的Group、DataId或服务名称。
命名空间创建完成后,将命名空间ID配置在应用中。服务注册时会根据配置注册到指定的命名空间中,如果没有指定命名命名空间,会默认注册到public。如果注册到一个不存在的命名空间ID,也能够提示注册成功,但是在控制台无法可视化操作该服务,创建对应的命名空间后就可以正常操作了。
配置代码:Spring Cloud yml方式(properties方式同理)
spring:
cloud:
nacos:
config:
server-addr: ${NACOS_SERVER_ADDRESS}
namespace: ${NACOS_CONFIG_NAMESPACE}
discovery:
server-addr: ${NACOS_SERVER_ADDRESS}
namespace: ${NACOS_NAMING_NAMESPACE}
Dubbo yml方式(properties方式同理)
dubbo:
registry:
address: nacos://Nacos地址
parameters[namespace]: 命名空间ID
生产环境下-Nacos引擎设置多少个节点比较好呢?
- 购买实例前建议您先评估实际需求,然后参考章节:产品规格 ,预留30%左右的容量,然后订购对应能力规格的产品。
- Nacos提供单机版和集群版,单机版只有一个节点,不建议生产使用。集群版提供3、5、7、9节点集群,集群节点数量越多,对故障节点数量的容错能力就越强,只要查过半数的节点正常就能正常提供服务例如9节点集群,即使同时有4个节点宕机或故障,依然能正常提供服务。建议您根据实际的需要以及服务的可用性要求订购对应的实例。
- 如果购买的实例无法随着业务发展无法满足实际需求可以使用扩容操作。具体的操作可以参考章节:管理实例
如何重启实例?
在实例出现节点异常,或者修改了Nacos实例重启生效的参数后,需要重启实例。MSE控制台页面支持重启实例和重启节点,可以根据业务需求进行选择,参考章节:管理实例
全量重启
在实例列表页面,单击目标实例ID、实例名称或者目标行“管理”按钮均可跳转至实例基础信息页面。基础信息右上角点击重启实例,即可重启整个实例。
节点重启
如果实例正在提供服务,则建议,在实例列表中每个实例的操作栏中分步骤进行滚动重启。
在实例列表页面,单击目标实例ID、实例名称或者目标行“管理”按钮均可跳转至实例基础信息页面。
在下方实例节点部分,可以看到节点列表,点击目标节点对应行右侧的操作按钮,即可重启目标节点。
如何创建专属账户给客户端提供服务?
MSE中Nacos引擎默认开启鉴权功能,访问未认证或者授权的用户访问实例。
Nacos鉴权默认支持JWT认证,通过用户、角色、权限三者共同作用来赋予用户权限,详情请参见章节Nacos引擎访问权限 。
创建用户页面示例如下:
JWT认证方式配置:
spring:
cloud:
nacos:
config:
server-addr: 访问地址
username: 用户名
password: 密码
是否支持回滚配置的历史版本?
MSE 注册配置中心提供了配置历史查询功能。目前默认仅保存30天以内的变更记录。查看和回滚历史配置。
在基础信息页面,左侧菜单点击配置管理>配置列表,选择命名空间,查看当前配置。在左侧导航栏,选择历史版本。在历史版本页面选择命名空间、分组、和DataId,点击搜索,即可查看配置的历史。详细操作请参见章节配置管理。
在配置历史页面选择指定版本的历史配置,点击回滚,确认后即可回滚至历史版本。
在配置列表页面点击编辑按钮,可以查看当前配置的内容,可以确认是回滚至历史版本。回滚操作也会产生一条新的配置变更记录。
Nacos 实例登陆失败如何解决 ?
问题现象
程序连接Nacos时出现以下错误。
login failed.
caused:No Authentication Provider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
问题原因
- 应用程序中配置了Nacos的username和password,且开启Nacos的鉴权功能,但传入的username和password不正确,导致login failed。
- 用户配置的AcccessKey和SecurityKey不正确,导致认证失败。
- 未开启认证时传递了错误的认证属性字段
解决方案
- 检查Nacos实例是否已经打开鉴权功能。具体操作,请参见Nacos引擎访问权限。
- 检查应用配置,是否有配置Nacos的username和password。未开启认证时需去掉这两个配置项。
- 若直接使用Nacos Client,需检查Client配置的信息。若存在,请移除该部分信息后重试。
properties.put(PropertyKeyConst.SERVER_ADDR, "${mseNacos实例域名}");
properties.put(PropertyKeyConst.USERNAME, "${username}");
properties.put(PropertyKeyConst.PASSWORD, "${password}");// 注册中心NamingService namingService = NamingFactory.createNamingService(properties);// 配置中心ConfigService configService = ConfigFactory.createConfigService(properties);
- 若使用Spring Cloud,请检查应用配置是否完成了以下配置。若存在,请移除该部分信息后重试。
#注册中心
spring.cloud.nacos.discovery.username=
spring.cloud.nacos.discovery.password=
#配置中心
spring.cloud.nacos.config.username=
spring.cloud.nacos.config.password=
- 若使用Dubbo, 请检查配置的注册中心URL上是否存在username或password参数。若存在,请移除该部分信息后重试。例如:
dubbo.registry.address=nacos://${访问地址}:47588?username=&password=
- 若没有在应用配置中找到配置Nacos的username和password,且使用的是Spring Cloud,请在部署环境中检查启动参数以及环境变量是否包含相关信息。若存在,请移除这部分信息后重试。
Nacos上修改服务实例的权重不生效问题
问题现象
控制台服务详情页面修改服务实例时,设置了实例的权重,但实际调用流量时,流量分配未按照预期权重进行分配。
问题原因
- 应用框架不支持按权重分配流量负载均衡。
- 应用框架有自身的负载均衡配置方式,不使用Nacos的权重属性进行负载均衡。
- 应用未使用权重值进行地址选择。
解决方案
Nacos中服务实例的权重仅为实例的一个属性。当修改权重值后,权重值会伴随实例信息被推送到Nacos客户端。实际使用时由于使用方式的不同,可能会导致权重属性被忽略。
- 如果所使用的应用框架不支持按权重分配流量。例如Spring Cloud等框架,此类框架仅识别流量值为0(不引入流量)和非0(引入流量),不支持按照Nacos实例中的流量值进行流量负载均衡。您可以按照以下方法解决。
- 寻找扩展插件以增加流量分配支持。
- 更换其他应用框架。
- 应用框架有自身的负载均衡配置方式,不支持使用Nacos的权重属性。如Dubbo、Spring Cloud Alibaba + Loadbalance等。可以在社区中询问或根据对应框架文档查看如何配置负载均衡。
- 未使用应用框架进行开发,但是应用在处理时未使用权重值进行地址选择。
应用在获取到实例列表后,根据其中的weight字段实现自定义的选择逻辑。
使用Nacos客户端默认的selectOneHealthyInstance方法进行选择。
微服务发布或上下线影响业务问题
问题现象
当应用处于发布、重启等过程时,上游服务发起的请求可能转给正在停止的下游服务,导致出现业务报错(例如链接超时、业务报错等)。
问题原因
- 请求发起后下游服务处于停止过程中,导致请求不被响应。
- 下游服务停止耗时较长,导致从注册中心无法及时注销服务。
- 下游服务停止完毕后,但上游服务因某些原因没有及时接受和处理下游服务地址更新后的列表。
- 使用了旧版本的客户端,由于机制问题移除下线的地址列表时效性较低。
解决方案
- 最佳方式是接入服务治理的无损发布功能。
- 查看上游服务的Nacos客户端日志,在日志中检索下游服务的名字及关键字current ips,并比较下游服务的变更时间、Nacos客户端日志信息的时间及上游服务报错的时间。若三者基本一致(即发起下游服务变更后,上游服务开始报错,但Nacos客户端日志信息出现后,上游服务报错停止),则说明程序正常,可使用下文的通用解决方案。
- 如果下游服务的变更时间、Nacos客户端日志信息的时间基本一致,但上游服务报错的时间始终未恢复,说明Nacos服务端正确推送了地址,且Nacos客户端也接收到了地址,但应用程序未使用。您可以按照如下方法进行排查:
- 查看是否存在缓存机制且缓存更新出错。
- 开源框架使用者可以到对应社区寻求帮助。
- 若下游服务的变更时间、Nacos客户端日志信息的时间基本一致,但上游服务报错的时间恢复很慢,说明Nacos服务端正确推送了地址且Nacos客户端也接收到了地址,但应用程序未立刻使用,可以按照以下方法排查。
- 检查应用自身是否有缓存机制并且缓存更新存在延迟问题。
- 检查是否使用ribbon、feign、loadbalance等辅助框架,此类框架存在地址列表缓存且更新时间较慢,请根据对应框架修改缓存刷新配置。
- 若排查后仍无法解决,可使用下文的通用解决方案。更多信息,请参见通用解决方案。
- 若下游服务的若下游服务的下若下游服务的变更时间与Nacos客户端日志信息的时间、上游服务报错的时间相差较大,说明下游服务变更未被Nacos客户端感知到,可以按照以下方法排查。
- 将上游服务和下游服务的Nacos客户端升级至2.X及以上版本。
- 查看上游服务是否存在网络故障、资源不足等问题。
- 排查下游服务停止时是否存在阻塞逻辑,导致应用无法响应请求但注册中心仍旧存在。
- 若排查后仍无法解决,可使用下文的通用解决方案。更多信息,请参见通用解决方案。
通用解决方案
下游服务停止前,需要使用Nacos更新实例OpenAPI修改enabled=false或在MSE控制台下线实例。随后通过监控、日志等手段,确认该下游服务节点已没有请求。
停止下游服务节点,执行变更。
确认变更下游服务节点完成,下游服务节点能够正确提供服务后,需要使用Nacos更新实例openAPI修改enabled=true或在MSE控制台上线实例。更多信息,请参见OpenAPI和上线应用实例。
Nacos连接超时问题
问题现象
当程序连接Nacos出现超时问题时,可能出现如下几种报错:
Connection timed out
Read Timeout
TimeoutException: Waited 3000 milliseconds
问题原因
可能是以下几种原因,导致程序连接Nacos出现超时问题。
- 客户端与服务端的网络传输异常,导致客户端发出的请求无法抵达服务端或服务端的回复无法抵达客户端。或者服务端处理请求速度慢,导致客户端误认为超时。
- 使用VPN导致的网络问题。
- 客户端的处理线程阻塞或异常,亦或客户端处于Full GC、OOM或CPU争抢等状态, 无法及时处理服务端返回的数据包,导致客户端误认为超时。
- Nacos集群处于异常状态,无法响应请求
解决方案
- 如果仅有某一个客户端节点出现超时报错,可能是这些客户端节点与Nacos之间的网络出现问题,或是这些客户端节点存在异常或阻塞。
此时,您可在错误所在的客户端节点上,使用ping、telnet和curl等命令,访问Nacos集群。查看客户端监控是否存在高CPU使用率、频繁FullGC和OOM等信息,以此排查是否存在网络问题。
ping ${mse.nacos.host}
telnet ${mse.nacos.host}:47588
curl ${mse.nacos.host}:47588/nacos/v1/ns/service/list
- 如果使用了VPN,请关闭VPN或查看VPN设置后重试。
- 如错误信息存在于所有的客户端节点,可以在监控分析页面查看Nacos实例的监控信息:
- 在概览页签,查看引擎的每秒查询数和每秒操作数是否超过了每秒处理请求数(TPS)。
- 关于每秒处理数的取值,请参见实例能力评估。
- 在连接数监控页签,查看客户端版本数量和长链路数量是否超过了连接数。
- 关于连接数的取值,请参见实例能力评估。
- 在jvm监控页签,查看引擎Full GC是否频繁出现。
- 当通过ELB访问Nacos时,查看资源的入口流量和出口流量是否超出购买时指定的带宽大小。
- 在系统资源监控tab页查看资源的内存使用率和CPU使用率是否接近或超过100%,导致实例出现异常。
- 如果仅是偶尔发生超时错误,考虑设置更长的超时时间避免此类问题。
- 若Java Client版本为1.0.0~1.4.X,则建议升级客户端版本到2.x系列版本。
- 若Java Client版本为2.0.0~2.1.1, 请将Java Client版本先升级至2.1.2及以上,再设置超时时间。
- 若Java Client版本为2.1.2及以上,请在应用进程的JVM参数中添加如下参数:
-Dnacos.remote.client.grpc.timeout=${请求超时,单位毫秒,默认3000}
检测所连接的服务端是否健康,不健康则触发重连
-Dnacos.remote.client.grpc.server.check.timeout=${服务端健康检测,单位毫秒,默认3000}
检测当前连接状态是否健康,不健康则触发重连
-Dnacos.remote.client.grpc.health.timeout=${连接健康检测,单位毫秒,默认3000}
Nacos连接失败问题
问题现象
当程序连接Nacos出现连接失败问题时,可能会出现如下几种报错。
Client not connected,currentstatus:STARTING
Client not connected,currentstatus:UNHEALTHY
no available server, currentServerAddr: xxxxx
Connection refused
问题原因
可能是如下几种原因,导致程序连接Nacos出现连接失败。
Nacos的访问地址或端口配置错误。
访问Nacos集群时,网络异常。
使用VPN导致的网络问题。
客户端存在高CPU使用率、频繁FullGC等问题。
解决方案
- 在错误所在的客户端节点上,使用ping、telnet和curl等命令,访问Nacos集群,排查是否存在网络问题。
ping ${mse.nacos.host}
telnet ${mse.nacos.host}:47588
telnet ${mse.nacos.host}:48588
curl ${mse.nacos.host}:47588/nacos/v1/ns/service/list
- 检查应用的相关配置,是否配置了正确的MSE实例访问地址、端口等信息。
- 如果报错信息为Connection refused ,请从紧随其后的报错信息中查看实际连接的地址与MSE实例的连接地址是否不相同。例如Connection refused: /127.0.0.1:48588说明某些配置错误地指向了本机地址。
- 如果使用了VPN,请检查VPN设置是否正确。若不正确,请关闭VPN或修改VPN设置后重试。
- 若通过上述步骤还无法定位问题,注册配置中心控制台的监控分析页面,查看Nacos的如下信息:
- 在概览页签,查看引擎的每秒查询数和每秒操作数是否超过了每秒处理请求数(TPS)。
- 关于每秒处理数的取值,请参见实例能力评估。
- 在连接数监控页签,查看长链路数量是否超过了连接数。
- 关于连接数的取值,请参见实例能力评估。
- 在jvm监控页签,查看引擎是否频繁出现Full GC。
- 在资源监控页签,查看资源的入口流量和出口流量是否超出购买时指定的带宽大小。
- 在资源监控页签,查看资源的内存使用率和CPU使用率是否接近或超过100%,导致节点可能出现异常。
- 资源的内存使用率和CPU使用率接近或超过100%,请尝试变更实例规格进行升配,请参见变更实例规格。
Nacos绑定的ELB域名无法解析问题
问题现象
当程序连接Nacos出现绑定的域名无法解析时,可能会有如下几种报错。
UnknownHostException
No route to host
Unable to resolve host
问题原因
应用节点所配置的DNS服务器或NameServer不正确,导致无法解析MSE域名。
容器未使用宿主机的DNS服务器或NameServer,或网络模式错误,导致无法解析MSE域名。
应用节点所配置的DNS服务器或NameServer故障,特别是Kubernetes集群所依赖的CoreDNS故障,导致无法解析MSE域名。
解决方案
使用ping命令
- 使用ping ${mse.nacos.host}指令尝试解析。
如果提示unknown host,则无法解析域名。
如果提示PING ${mse.nacos.host} (xxx.xx.xx.xx) bytes of data.,则解析成功。
- 如果执行ping命令无法正常解析,可查看文件/etc/resolv.conf的内容,获取DNS服务器和NameServer地址信息,尝试采用以下方式修复:
如果是通过Docker或Kubernetes部署,请退出到宿主机或Node上再次执行ping命令尝试解析。
如果解析成功,说明是网络模式错误或容器内外的DNS服务器和NameServer设置不同,尝试修改部署的网络模式,或将Node上的/etc/resolv.conf配置移植到容器中重试。
如果无法解析,请提工单联系技术支持协助排查域名解析失败的原因。
- 如果执行ping命令可以正常解析,且应用已经恢复不再出现异常,说明是DNS服务器或NameServer出现故障。
Nacos 持久化实例健康检查异常问题
问题现象
当在Nacos中注册的持久化实例选择健康检查方式为HTTP/TCP时,服务实例的健康状态始终显示为不健康,但实例配置或状态正常。
可能原因
MSE的Nacos为托管类产品,部署在内外资源池的诶vpc中,不与应用程序部署在一起。出于安全规范的考量,仅开放单向请求,在网络层面禁止从服务端向外部发起的TCP连接/HTTP请求。上述原因可能导致健康检查始终会以超时等网络原因显示失败。
解决方案
将注册的服务类型修改为非持久化。即注册服务提供者时,指定ephemeral字段为true或移除对ephemeral字段的设置(ephemeral字段缺省值为true)。
应用服务重启后健康状态正常但处于下线状态问题
问题现象
应用服务在重启或发布后,在Nacos上查询该服务的上线状态为下线,但健康状态为正常的绿点。
可能原因
应用服务在注册该服务时,将enabled字段设置为false。
在应用停止时,调用过OpenAPI将enabled字段设置为false。在1分钟内又重新注册回Nacos,下线的元数据没有因为过期被删除而被重新复用。
解决方案
- 在应用订阅者节点上查找Nacos-Client的日志。
- 过滤关键字REGISTER-SERVICE并找到注册服务提供者的日志信息,查看提供者详细信息中的enabled字段。
如果注册时enabled字段值为false。则修改应用启动时,注册服务提供者的enabled字段值为true,或者删去对enabled字段的设置(其默认值已为true)。或通过OpenAPI 更新实例,将enabled字段设置为true。
如果注册时enabled字段值为true。则移除程序停止时自动调用OpenAPI修改的enabled字段。确保停止服务提供者(注销、自动移除)和重新注册服务提供者的间隔大于1分钟。在服务提供者确认自身启动完毕后,调用Nacos OpenAPI v1版本中的修改实例或OpenAPI v2版本中的更新实例,设置enabled字段为true。
如何查找Nacos-Client日志
Nacos-Client的日志根据相关的编程语言不同而有所差异,不同的编程语言版本Client的日志获取方式如下。
Java Nacos Client
Java语言的Nacos-Client的日志一般在应用服务所在节点的{user.home}/logs/nacos/目录下 ,{user.home}为启动应用服务进程的系统用户的根目录。
若使用的是Spring Cloud,部分低版本Spring Cloud会覆盖Nacos-Client的日志配置,导致日志输出在应用服务的日志中。
其中,naming.log是注册中心模块相关日志,config.log是配置中心模块相关日志。2.0.0之后版本中,Nacos-Client新增了remote.log,remote.log是gRPC连接相关的日志。
Go Nacos-Client
Go语言的Nacos-Client的日志默认在/tmp/nacos/log/目录下,可以通过LogDir:参数修改日志路径。
Go语言的Nacos-Client日志不区分具体模块内容,应该所有的日志都会在同样的日志文件中。
Python Nacos-Client
Python语言的Nacos-Client使用Python的Logging模块,会和应用的Logging模块保持一致并输出到应用的日志中。
C++ Nacos-Client
C++语言的Nacos-Client的日志默认在应用所在目录下,文件名为nacos-sdk-cpp.log, 可通过Logger.cpp中的setBaseDir设置日志目录。
引擎升级或重启时,出现访问异常或中断服务
集群升级或重启会轮转进行。不同节点数量的集群可能出现的情况不同。
- 3个节点以上的集群:不会出现中断服务,无法访问的情况,但仍可能出现少量的短时间的请求失败,引擎会立刻重试恢复。
- 单节点集群:会导致集群不可用并中断服务。仅开发版集群为单节点,不保证高可用。
控制台还能查到不存在的服务实例IP如何处理的
问题现象
应用服务实例停止,注册配置中心控制台仍能看到该服务实例。
应用服务重启或发布后,注册配置中心控制台仍能看到该服务实例。
可能原因
服务实例并未彻底关闭,进程仍然存在并发送心跳维持连接,导致Nacos未摘除服务提供。
有额外的应用进程在发送心跳维持连接,导致Nacos未摘除服务提供者。
解决方案
- 确认该服务实例已经不应该在线的情况下,先在MSE控制台上对该服务提供者执行下线操作,防止有更多流量进入到该故障节点。
- 根据部署环境的不同排查服务提供者是否未彻底关闭:
直接部署到云主机:登录到对应IP的云主机上,使用ps -ef | grep ${应用名}、netstat -anp | grep 48588或netstat -anp | grep 47588等命令,查看服务提供者进程是否还存在,是否与Nacos还保持着连接。如果是,则确认后关闭该进程。
通过自建Kubernetes、Docker或容器服务部署:检查是否存在幽灵Pod或Container(即Pod或Container已经不可见,但对应的程序进程未终止销毁),可通过在Node或宿主机上执行**ps -ef | grep ${应用名}**等命令,查看是否该应用提供者的个数等同于期望个数。如果不相同,则确认后找到该幽灵Pod并彻底关闭。
服务实例已关闭,但是还在被其他应用调用
问题现象
其他应用调用依赖的服务时报错,错误信息显示仍然在调用一个已经下线或停止的服务实例的IP地址。
可能原因
服务实例并未彻底关闭,进程仍然存在并发送心跳维持连接,导致Nacos未摘除服务实例。或有额外的应用进程在发送心跳维持连接,导致Nacos未摘除服务实例。
停止服务实例后,该服务已经没有可用的提供者,触发了推空保护。
网络问题或订阅者应用有问题,导致Nacos-Client未获取到最新的服务实例列表。
Nacos-Client已经获取到最新的服务实例地址,但应用未使用(如有路由规则、权重规则、框架缓存等)。
解决方案
- 在MSE控制台查看该服务提供者是否还存在,具体操作方式参考管理服务。
- 如果控制台上仍然能看到该服务提供者IP,则解决方案请参考问题【控制台还能查到不存在的服务实例IP如何处理的】 。
- 如果控制台上已经看不到该服务提供者IP,且服务下已经没有服务提供者或所有服务提供者均为下线状态,那么应该是触发了推空保护,可以关闭推空保护。
- 如果控制台上已经看不到该服务提供者IP,但服务下仍有其他非下线状态的服务提供者,则解决方案可以参考问题【应用服务调用的服务实例与预期不符】。
应用服务调用的服务实例与预期不符
问题现象
应用服务调用了依赖服务的提供者时,提示No provider或找不到服务等错误。
应用服务调用了依赖服务的提供者重启或发布后,IP地址发生变更但应用服务仍然在调用旧的提供者地址。
可能原因
服务提供者未注册或注册至错误环境内。
网络问题或订阅者应用有问题,导致Nacos-Client未获取到最新的服务提供者地址。
Nacos-Client已经获取到最新的服务提供者地址,但应用未使用(如有路由规则、权重规则、框架缓存等)。
解决方案
(1) 从控制台上查看该服务的提供者是否存在,且数量及地址是否符合预期。若在控制台上看到预期的服务提供者不存在,解决方案请参考服务提供者注册失败。
(2) 如果控制台上仍然能看到旧服务提供者IP地址,解决方案请参考控制台还能查到不存在的服务提供者IP链接怎么办。
(3) 若控制台上服务存在且地址符合预期,可通过以下操作确认地址是否推送成功:搜索该服务或订阅者IP的推送轨迹,是否存在记录。存在记录则为推送成功。
在应用订阅者节点上找到Nacos-Client的日志,检索关键字current ips以及对应的服务名,查看日志中的服务提供者实例个数及对应的详细信息是否与控制台上的一致。一致则确认Nacos-Client已收到推送。
(4) 通过上述操作,若已确认服务提供者列表已经成功推送,表明应用自身未使用最新服务提供者地址。请根据应用所使用框架,或应用自身逻辑出发,排查问题原因。该问题经常出现在以下场景。
Spring Cloud框架使用Feign/Loadbalance/Robin等辅助插件框架时,由于其存在自身缓存/路由规则,会导致Nacos-Client中最新的服务提供者地址不被使用或被延迟使用。
Dubbo 2.7.7~2.7.16存在多订阅问题,有可能出现推送的最新地址不被使用的问题。请升级至2.7.17以上版本或开启推空保护规避。
(5) 若通过上述操作未发现服务提供者列表已经成功推送,可通过Nacos-Client的日志查看推送出错的原因。
如出现read time out、connected timeout等超时字样,则参考Nacos连接超时问题。
如出现UnknownHostException、Unable to resolve host等域名无法解析问题,则参考域名无法解析的问题
如果使用2.0.0~2.0.4版本Nacos-Client,且应用中依赖org.reflections工具包,则可能是该工具包冲突导致。请设置org.reflections工具包为0.9.11版本或升级Nacos-Client至2.1.0及以上版本。
服务实例注册失败
问题现象
应用启动后,在MSE控制台上无法看到该服务提供者。
可能原因
配置了错误的域名、端口、命名空间等信息。
未连接到Nacos实例中,而是连接到其他环境。
应用代码存在问题,导致未进行服务注册。
网络问题导致注册失败。
解决方案
(1)首先核对应用是否配置了正确的域名、端口、命名空间等信息,然后找到Nacos-Client日志,并从中查看实际生效的域名、端口、命名空间等信息。如果实际生效的信息中有错误,请排查应用是否读取了正确的配置文件。
(2) 若您直接通过云主机等方式部署,也可以找到Nacos-Client日志,检索关键字REGISTER-SERVICE。
如不存在内容,则表明应用代码存在问题,未发起该服务的注册。
如存在内容,但服务名与预期不符,则表明应用代码存在问题,发起了错误的服务注册。
(3) 若通过上述操作发现服务提供者已经发起注册,可通过Nacos-Client的日志查看注册出错的原因。
如出现read time out、connected timeout等超时字样,则参考Nacos连接超时问题。
如出现UnknownHostException、Unable to resolve host等域名无法解析问题,则参考域名无法解析的问题。
如出现Client not connected,currentstatus:STARTING、Connection refused等问题,请参考解决Nacos实例连接失败问题。
排查Nacos线程数过多的问题
通过监控系统或其他手段,观察到应用的线程数过多,且大部分线程名中带有nacos等字样。
可能原因
程序读取到的CPU数量错误,导致线程池核心大小和最大大小过大。
应用中创建过多Nacos-Client实例, 例如NacosNamingService或NacosConfigService
应用使用客户端方式错误,连续创建Nacos-Client实例,但新创建的Nacos-Client实例替换旧的Nacos-Client实例时未使用shutdown方法关闭线程池。
解决方案
本文以Java应用为例,其他语言应用可使用对应开发语言的相似命令执行。
(1) 首先确认是否创建过多Nacos-Client实例,使用jmap -histo ${pid} > histo.log命令,将应用中的内存实例对象记录在日志文件中,随后对日志文件进行过滤统计,并记录Nacos-Client的数量。
Nacos-Client注册中心客户端数量,正常情况下应该不超过3个。
grep "NacosNamingService" histo.log | awk '{print $2,$4}'# Nacos-Client配置中心客户端数量,正常情况下应该不超过3个。
grep "NacosConfigService" histo.log | awk '{print $2,$4}'
如果Nacos-Client实例数存在过多,例如10个以上,则原因可能为应用中创建了过多Nacos-Client实例。请排查应用中使用Nacos-Client的代码,是否未复用Nacos-Client实例而是每次都创建不同的Nacos-Client实例。
(2) 如果Nacos-Client实例数量正常,请确认线程数是否符合预期。
使用jstack ${pid} > jstack.log命令,将当前线程信息打印到日志文件中,随后对日志文件进行过滤统计。
Nacos-Client所使用的线程池数量,其数量不应该超过Nacos-Client数量 cpu数 * 8。
grep "nacos-grpc-client-executor" jstack.log | wc -l
Nacos-Client内部事件通知机制所使用的线程池,其总数不应超过5个
grep "nacos.publisher-" jstack.log | wc -l
Nacos-Client用于断线重连及发送pingpong心跳的线程,其总数不应超过Nacos-Client数量 * 2。
grep "com.alibaba.nacos.client.remote.worker" jstack.log | wc -l
Nacos-Client注册中心更新缓存所使用的线程池,其总数不应超过NacosNamingService数量 * (cpu数 / 2)。
grep "com.alibaba.nacos.client.naming.updater" jstack.log | wc -l
Nacos-Client注册中心接收UDP推送数据所使用的线程池,其总数不应超过NacosNamingService数量。
grep "com.alibaba.nacos.naming.push.receiver" jstack.log | wc -l
Nacos-Client注册中心在断线重连后,补偿非持久化服务数据的线程,其总数不应超过NacosNamingService数量。
grep "com.alibaba.nacos.client.naming.grpc.redo" jstack.log | wc -l
Nacos-Client配置中心监听配置所使用的线程池,其总数不应超过NacosConfigService数量。
grep "com.alibaba.nacos.client.Worker" jstack.log | grep -v "longPolling" | wc -l
Nacos-Client配置中心用于回调监听者Listener的线程池,其总数不应超过NacosConfigService数量 * 5。
grep "nacos.client.config.listener.task" jstack.log | wc -l
Nacos-Client配置中心监听长轮询所使用的线程池,其总数不应超过NacosConfigService数量 * cpu数量。
grep "com.alibaba.nacos.client.Worker.longPolling" jstack.log | wc -l
如果上述线程数均超过了预期,则原因可能为连续创建Nacos-Client实例,但新创建的Nacos-Client实例替换旧的Nacos-Client实例时未使用shutdown方法关闭线程池,导致旧线程池未被关闭。更多信息,参考Sentinel框架在旧版本中的Bug。
如果上述线程数仅有nacos-grpc-client-executor、com.alibaba.nacos.client.naming.updater等与CPU数量有关的线程数超过预期,则原因可能为应用读取的当前节点的CPU数量不正确,该情况多出现于容器化的场景中。可通过调用Runtime.getRuntime().availableProcessors()查看应用读取到的CPU数量,确认读取数量过大时,可通过更换正确的环境进行修复,或使用参数-Dnacos.common.processors或环境变量NACOS_COMMON_PROCESSORS进行强制指定(需要Nacos-Client版本为2.1.1及以上版本生效)。
如果上述线程均符合预期,说明线程池并没有泄漏,没有线程数过多的风险。如需降低线程数,可通过参数-Dnacos.remote.client.grpc.pool.core.size和-Dnacos.remote.client.grpc.pool.max.size来设置nacos-grpc-client-executor线程池的数量(需要Nacos-Client版本为2.1.1及以上版本)。
nacos-grpc-client-executor线程池存在回收机制,客户端在长时间无请求时,会自动回收多余线程至最小值(默认为CPU数量 * 2)。在大量请求时,会自动扩充线程数至最大值(默认为CPU数量 * 8)。因此部分监控系统中会看到该线程名的线程ID会呈现增长趋势,该现象为正常现象,并非Nacos线程数过多的问题。
Nacos-sdk连接Nacos出现The maximum number of tolerable server reconnection报错
问题现象
使用Nacos-sdk连接MSE时出现The maximum number of tolerable server reconnection报错。
可能原因
Nacos的配置中心的客户端尝试连接服务端失败。
使用了公网连接Nacos,但由于网络原因导致客户端无法连接MSE服务端,使用Telnet或者Ping工具检查网络连通性。
使用了内网连接Nacos,但客户端和Nacos没有处于同一个VPC内。
Nacos服务端正在重启中。
解决方案
- 先确定Nacos集群状态是否异常。
在左侧导航栏选择基础信息,然后在实例节点区域查看各节点的状态是否为运行中。
- 首先检查是否仅使用了Nacos的服务发现功能,没有使用配置中心功能。
如果没有使用配置中心功能,请将如下依赖删除。
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
如果已使用配置中心功能,请检查${user_home}/logs/nacos/config.log判断是否为网络问题。
- 如果使用的是Spring Cloud,部分低版本Spring Cloud会覆盖Nacos-Client的日志配置,导致日志输出在应用服务的日志中。
如出现read time out、connected timeout等超时字样,参考问题Nacos连接超时问题。
如出现UnknownHostException、Unable to resolve host等域名无法解析问题,则参考问题Nacos绑定的ELB域名无法解析问题。
使用Nacos-client发布配置失败
本文介绍如何解决使用nacos-client发布配置失败的问题。
问题现象
使用如下API发布配置,返回结果为false,表示发布失败,控制台上也未出现预期的配置。
public boolean publishConfig(String dataId, String group, String content) throws NacosException;
问题原因
网络问题导致Nacos-Client未连接成功。
使用了内网连接Nacos,但客户端和Nacos没有处于同一个VPC内。
使用了公网连接Nacos,但被黑白名单拦截。
没有传入AK、SK导致鉴权失败。
配置内容存在特殊字符。
解决方案
- ELB公网连接问题
如果使用了ELB公网地址连接,请在控制台上检查是否开启了黑白名单,以及请求是否被黑白名单拦截。
- 内网连接问题
如果使用了内网连接,请保证客户端机器和Nacos处于同一个VPC内
Nacos所属的VPC的vpc Id可以通过MSE控制台实例详情页面查到。
- 鉴权问题
检查${user_home}/logs/nacos/config.log,如果发现403字样,则为鉴权问题,请为当前账号授予正确的权限。可在控制台左侧菜单栏权限控制页面查看和修改用户权限。
说明Nacos-Client的日志一般在节点的${user.home}/logs/nacos/config.log下,${user.home}为启动应用服务进程的系统用户的根目录。若使用的是Spring Cloud,需要注意部分低版本Spring Cloud会覆盖Nacos-Client的日志配置,导致日志混合输出。
- 配置问题
请检查是否存在非ascii码特殊字符。
- 网络问题
若通过上述操作未发现配置已经成功拉取,可通过Nacos-Client的日志查看推送出错的原因。
如出现read time out、connected timeout等超时字样,参考问题Nacos连接超时问题。
如出现UnknownHostException、Unable to resolve host等域名无法解析问题,则参考问题Nacos绑定的ELB域名无法解析问题。
如果使用的Nacos-Client版本为2.0.0~2.0.4,且应用中依赖了org.reflections工具包,则可能是该工具包冲突导致,请设置org.reflections工具包为0.9.11版本或升级Nacos-Client至2.1.0及以上版本。