背景
Nacos 作为一个微服务的注册中心和配置中心,其高可用性对整个微服务系统的稳定性至关重要。然而,目前很多微服务对 Nacos 的健康状态有着强依赖性,例如通过健康探测接口 /api/status/ready
来监控 Nacos Server 的健康状况。如果 Nacos Server 不健康,相关的微服务实例会被 K8s 下线,这会导致服务中断。
为了提升系统的高可用性,我们希望在 Nacos 不可用时,依然能够正常使用缓存的旧服务列表,保证服务的正常调用。本文将详细探讨如何通过配置启动参数,屏蔽 Spring Actuator 对 Nacos 的探测,从而实现这一目标。
技术探讨
配置参数
在微服务启动参数中添加以下配置:
-Dmanagement.health.nacos-discovery.enabled=false
-Dmanagement.health.nacos-config.enabled=false
这两个参数用于禁用 Spring Actuator 对 Nacos 服务发现和配置的健康检查。通过这些配置,即使 Nacos Server 不可用,微服务仍然会使用 Nacos Client 的缓存数据来继续提供服务。
工作原理
Nacos Client 内置了缓存机制,当 Nacos Server 不可用时,Nacos Client 会使用缓存的旧服务列表进行服务调用,从而保证服务的连续性。通过禁用健康检查,我们可以避免因为 Nacos Server 短暂不可用而导致微服务实例被 K8s 下线的情况。
测试方法
为了验证上述配置的有效性,我们可以进行以下测试步骤:
- 启动本地服务:启动你的本地微服务,并确保其正常运行。
- 修改 Nacos 地址:将本地微服务的 Nacos 地址修改为一个无法访问的地址,模拟 Nacos Server 不可用的情况。
报错信息如下:
[com.alibaba.nacos.client.config.impl.ClientWorker] 398 ERROR [checkUpdateConfigStr] -->[check-update] get changed dataId exception java.net.ConnectException: [NACOS HTTP-POST] The maximum number of tolerable server reconnection errors has been reachedat com.alibaba.nacos.client.config.http.ServerHttpAgent.httpPost(ServerHttpAgent.java:170) ~[nacos-client-1.2.1.jar:?]at com.alibaba.nacos.client.config.http.MetricsHttpAgent.httpPost(MetricsHttpAgent.java:64) ~[nacos-client-1.2.1.jar:?]at com.alibaba.nacos.client.config.impl.ClientWorker.checkUpdateConfigStr(ClientWorker.java:386) [nacos-client-1.2.1.jar:?]at com.alibaba.nacos.client.config.impl.ClientWorker.checkUpdateDataIds(ClientWorker.java:354) [nacos-client-1.2.1.jar:?]at com.alibaba.nacos.client.config.impl.ClientWorker$LongPollingRunnable.run(ClientWorker.java:521) [nacos-client-1.2.1.jar:?]at com.alibaba.ttl.TtlRunnable.run(TtlRunnable.java:59) [?:?]at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_241]at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) [?:1.8.0_241]at java.util.concurrent.FutureTask.run(FutureTask.java) [?:1.8.0_241]at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_241]at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_241]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_241]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_241]at java.lang.Thread.run(Thread.java:748) [?:1.8.0_241]
-
本地调用测试:检查本地服务是否依然可以正常调用,不受 Nacos 不可用的影响。
如果健康探测依然显示为
UP
,不会引起 K8s 探测导致 Pod 下线,说明配置生效。
故障演练
为了进一步验证方案的有效性,可以在测试环境中进行故障演练。具体步骤如下:
- 部署测试环境:在测试环境中部署大部分服务。
- 下线 Nacos Server:选择一个没有发布任务的晚上,下线测试环境的 Nacos Server。
- 观察服务状态:观察服务是否能正常访问,验证服务是否依然使用缓存的服务列表进行调用。
深入分析与优化
Nacos 缓存机制
Nacos Client 内置了缓存机制,在 Nacos Server 短暂不可用的情况下,Nacos Client 会使用本地缓存的服务列表和配置信息。这种机制保证了服务在短时间内不会受到 Nacos Server 不可用的影响。
Spring Actuator 与 Nacos 健康检查
Spring Actuator 提供了一套健康检查机制,用于监控各种依赖的健康状态。通过禁用 Nacos 的健康检查,我们可以避免因为 Nacos Server 短暂不可用而导致微服务实例被 K8s 下线的情况,从而提高系统的可用性。
主从复制与一致性
在使用 Nacos 的 AP 模式时,需要注意数据的一致性问题。AP 模式允许数据短暂不一致,以保证高可用性。通过合理配置和监控,可以在一定程度上缓解数据不一致带来的影响。
硬件与资源配置
确保服务器的硬件资源(如 CPU、内存、I/O 等)充足,以应对高并发和大数据量的请求。同时,合理配置数据库和缓存,提高系统的整体性能和稳定性。
监控与优化
使用监控工具(如 Prometheus、Grafana 等)监控服务的运行状态和性能指标,及时发现并解决潜在问题。同时,根据监控结果进行参数调整和优化,进一步提高系统的稳定性和可用性。
总结
通过禁用 Spring Actuator 对 Nacos 的健康检查,可以在 Nacos Server 短暂不可用时,依然使用缓存的旧服务列表,保证服务的连续性。这种配置可以有效减少因 Nacos Server 不可用导致的服务中断,提高系统的高可用性。同时,通过合理的监控和优化,可以进一步提升系统的性能和稳定性。通过以上步骤,您可以实现对 Nacos 的弱依赖,提高整个微服务系统的健壮性和可靠性。