实战:用HealthCheckProcessor实现Redis探活插件
用 HealthCheckProcessor 写了一个 Redis 探活插件3 小时省掉了 1 个运维脚本自定义健康检查实战文章目录用 HealthCheckProcessor 写了一个 Redis 探活插件3 小时省掉了 1 个运维脚本自定义健康检查实战Nacos 默认只能检查 TCP 和 HTTP但你的服务不止这两种HealthCheckProcessor 接口定义完整实现Redis 探活插件项目结构pom.xml核心实现类SPI 配置文件打包、部署、验证打包部署注册实例时指定检查类型验证扩展HTTP 接口探活插件一张图带走健康检查插件开发全流程Nacos 默认只能检查 TCP 和 HTTP但你的服务不止这两种Nacos 内置的健康检查支持两种协议TCP 端口探测和 HTTP 接口探活。大部分微服务用这两种就够了。但你有 Redis 实例、MySQL 实例、RabbitMQ 实例也在 Nacos 里注册了。它们的健康不是一个 TCP 端口通了就算——TCP 通了不代表 Redis 能读写不代表 MySQL 连接池没满。你需要一种自定义的健康检查方式连上 Redis 发个PING收到PONG才算健康。这篇文章用一个完整的例子走一遍 HealthCheckProcessor 插件的开发、打包、部署、验证全流程。代码可以直接拿去改。⚠️ 本文基于 Nacos Server 2.3.x。HealthCheckProcessor 接口在 2.0.0 后稳定。如果你用的是 1.4.x接口签名略有不同返回值是HealthCheckResult而非CheckResult。HealthCheckProcessor 接口定义// com.alibaba.nacos.naming.healthcheck.extend.HealthCheckProcessorpublicinterfaceHealthCheckProcessorextendsSpiExtension{/** * 执行健康检查 * param task 健康检查任务包含实例信息 * param cluster 集群信息 */voidprocess(HealthCheckTasktask,Clustercluster);/** * 返回这个 Processor 处理的检查类型名称 * 必须和实例注册时指定的 healthCheckType 一致 */StringgetType();}你需要实现 3 个方法方法作用你的实现process(task, cluster)执行实际的健康检查逻辑连 Redis 发 PINGgetType()返回检查类型标识REDISgetOrder()可选排序优先级默认 1000完整实现Redis 探活插件项目结构nacos-healthcheck-redis/ ├── pom.xml └── src/main/ ├── java/com/example/nacos/plugin/ │ └── RedisHealthCheckProcessor.java └── resources/META-INF/services/ └── com.alibaba.nacos.naming.healthcheck.extend.HealthCheckProcessorpom.xmlprojectgroupIdcom.example/groupIdartifactIdnacos-healthcheck-redis/artifactIdversion1.0.0/versiondependencies!-- Nacos Naming 接口provided不打包进去 --dependencygroupIdcom.alibaba.nacos/groupIdartifactIdnacos-naming/artifactIdversion2.3.0/versionscopeprovided/scope/dependency!-- Jedis轻量 Redis 客户端 --dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion4.4.3/version/dependency/dependenciesbuildplugins!-- 打包成 fat jar包含 Jedis 依赖 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-shade-plugin/artifactIdversion3.5.1/versionexecutionsexecutionphasepackage/phasegoalsgoalshade/goal/goals/execution/executions/plugin/plugins/build/project核心实现类packagecom.example.nacos.plugin;importcom.alibaba.nacos.api.naming.pojo.healthcheck.AbstractHealthChecker;importcom.alibaba.nacos.naming.healthcheck.extend.HealthCheckProcessor;importcom.alibaba.nacos.naming.healthcheck.extend.HealthCheckTask;importcom.alibaba.nacos.naming.pojo.Cluster;importredis.clients.jedis.Jedis;publicclassRedisHealthCheckProcessorimplementsHealthCheckProcessor{OverridepublicStringgetType(){returnREDIS;// 必须和注册实例时的 healthCheckType 一致}Overridepublicvoidprocess(HealthCheckTasktask,Clustercluster){// 从实例元数据中获取 Redis 地址Stringiptask.getIp();intporttask.getPort();// 从 metadata 读取密码可选Stringpasswordtask.getMetadata().getOrDefault(redis.password,);inttimeoutInteger.parseInt(task.getMetadata().getOrDefault(redis.timeout,2000));try(JedisjedisnewJedis(ip,port,timeout)){if(!password.isEmpty()){jedis.auth(password);}Stringpongjedis.ping();if(PONG.equals(pong)){// 健康检查通过task.setCheckResult(true);}else{// 响应异常task.setCheckResult(false);}}catch(Exceptione){// 连接失败或超时task.setCheckResult(false);}}Overridepublicvoidinitialize(){// 插件初始化可以预热连接池}Overridepublicvoidshutdown(){// 插件销毁关闭连接池}}SPI 配置文件# src/main/resources/META-INF/services/com.alibaba.nacos.naming.healthcheck.extend.HealthCheckProcessor com.example.nacos.plugin.RedisHealthCheckProcessor打包、部署、验证打包cdnacos-healthcheck-redis mvn clean package-DskipTests# 产出target/nacos-healthcheck-redis-1.0.0.jar部署# 把 jar 包复制到 Nacos Server 的 plugins 目录cptarget/nacos-healthcheck-redis-1.0.0.jar /home/nacos/plugins/# 重启 Nacos集群模式下逐台重启cd/home/nacos/binshshutdown.shshstartup.sh-mcluster注册实例时指定检查类型# 注册一个 Redis 实例到 Nacos指定 healthCheckType 为 REDIScurl-XPOSThttp://nacos:8848/nacos/v1/ns/instance\-dserviceNameredis-cluster\-dip10.0.1.50\-dport6379\-dephemeralfalse\-dmetadatahealthCheckTypeREDIS,redis.passwordmypassword\-dnamespaceIdprod关键点ephemeralfalse持久化实例服务端主动检查健康状态不走客户端心跳metadata.healthCheckTypeREDIS告诉 Nacos 用你的 REDIS 检查器metadata.redis.password你的插件从 metadata 读取密码验证# 查看实例健康状态curl-shttp://nacos:8848/nacos/v1/ns/instance\-dserviceNameredis-cluster\-dip10.0.1.50\-dport6379\-dnamespaceIdprod|jq.healthy# 期望true如果 Redis 在线且 PING 成功# 停掉 Redis 后再次检查# 期望false30 秒内 Nacos 会检测到健康检查失败扩展HTTP 接口探活插件如果你的服务有一个自定义的/health端点返回的 JSON 里包含多个组件的状态{status:UP,components:{db:{status:UP},redis:{status:DOWN},mq:{status:UP}}}你可以写一个 HTTP 探活插件解析这个 JSON任何一个组件 DOWN 就认为不健康publicclassDeepHealthCheckProcessorimplementsHealthCheckProcessor{OverridepublicStringgetType(){returnDEEP_HTTP;}Overridepublicvoidprocess(HealthCheckTasktask,Clustercluster){Stringurlhttp://task.getIp():task.getPort()/health;try{// HTTP GET /healthHttpURLConnectionconn(HttpURLConnection)newURL(url).openConnection();conn.setConnectTimeout(3000);conn.setReadTimeout(3000);if(conn.getResponseCode()200){StringbodynewString(conn.getInputStream().readAllBytes());// 检查所有组件状态booleanallUp!body.contains(\DOWN\);task.setCheckResult(allUp);}else{task.setCheckResult(false);}}catch(Exceptione){task.setCheckResult(false);}}}一张图带走健康检查插件开发全流程1. 开发实现 HealthCheckProcessor getType 返回标识2. 配置 SPIMETA-INF/services/写接口→实现类3. 打包mvn packagefat jar 含依赖4. 部署cp jar → plugins/重启 Nacos5. 注册实例ephemeralfalsemetadata.healthCheckTypeREDIS6. 验证查实例健康状态停服务看是否变 false⚠️ nacos-naming用 provided scope⚠️ shade 插件打包依赖⚠️ 集群模式逐台重启6 步走完全流程。每步下面有注意事项provided scope 不打包 Nacos 依赖、shade 插件打 fat jar、集群模式逐台重启。你们在 Nacos 里注册过非微服务的组件Redis、MySQL、MQ吗评论区留数字1注册过用 TCP 检查 2注册过写了自定义检查插件 3没注册过只用 Nacos 管微服务 4有这个需求先收藏