前言
问题现象
排查
其实很容易想到,这是默认心跳超时配置以及剔除策略配置导致的,然后各种 debug 源码以及官网 issue 搜索。
结论如下:
Nacos 1.1.0 以及之后的版本支持服务自定义心跳周期
之前的版本中,客户端注册服务时,不能自定义上报心跳的周期以及客户端下线时自动删除实例的间隔。在 1.1.0 中,我们支持了这个特性,应用可以在注册时,通过设置实例的 metadata,来指定心跳周期、健康检查过期时间及删除实例时间。具体举例如下:
String serviceName = randomDomainName();
Instance instance = new Instance();instance.setIp("1.1.1.1");instance.setPort(9999);Map<String, String> metadata = new HashMap<String, String>();// 设置心跳的周期,单位为秒,这里将心跳间隔设置为3秒:metadata.put(PreservedMetadataKeys.HEART_BEAT_INTERVAL, "3000");// 设置心跳超时时间,单位为秒,这里将心跳超时时间设为6秒,// 即服务端6秒收不到客户端心跳,会将该客户端注册的实例设为不健康:metadata.put(PreservedMetadataKeys.HEART_BEAT_TIMEOUT, "6000");// 设置实例删除的超时时间,单位为秒,这里将实例删除超时时间设为9秒,// 即服务端9秒收不到客户端心跳,会将该客户端注册的实例删除:metadata.put(PreservedMetadataKeys.IP_DELETE_TIMEOUT, "9000");instance.setMetadata(metadata);
naming.registerInstance(serviceName, instance);
复制代码
直接用上面的代码实测了是可以的
spring-cloud-starter-alibaba-nacos-discovery有相关配置如下
spring: application: name: nacos-producer cloud: nacos: discovery: server-addr: 10.7.11.13:8848 heart-beat-interval: 1 #心跳间隔。时间单位:秒。心跳间隔 heart-beat-timeout: 3 #心跳暂停。时间单位:秒。 即服务端6秒收不到客户端心跳,会将该客户端注册的实例设为不健康: ip-delete-timeout: 3 #Ip删除超时。时间单位:秒。即服务端9秒收不到客户端心跳,会将该客户端注册的实例删除:
复制代码
**但是不生效**,后抓包看了下,压根没有把配置的心跳设置发送到 Nacos 服务端。
继续分析代码
相关类如下
关键代码NacosServiceRegistry.getNacosInstanceFromRegistration:
private Instance getNacosInstanceFromRegistration(Registration registration) { Instance instance = new Instance(); instance.setIp(registration.getHost()); instance.setPort(registration.getPort()); instance.setWeight(nacosDiscoveryProperties.getWeight()); instance.setClusterName(nacosDiscoveryProperties.getClusterName()); instance.setEnabled(nacosDiscoveryProperties.isInstanceEnabled()); instance.setMetadata(registration.getMetadata()); // 就是这个 instance.setEphemeral(nacosDiscoveryProperties.isEphemeral()); return instance; }
复制代码
NacosServiceRegistryAutoConfiguration -1
NacosRegistration -2 首先实例化
NacosDiscoveryProperties - 3
2-3 顺序颠倒了。。。
解决方案:
解决方案
直接配置 Dicovery Metadata 数据
- preserved.heart.beat.interval: 1000 #心跳间隔。时间单位:秒。心跳间隔
- preserved.heart.beat.timeout: 3000 #心跳暂停。时间单位:秒。 即服务端 6 秒收不到客户端心跳,会将该客户端注册的实例设为不健康:
- preserved.ip.delete.timeout: 3000 #Ip 删除超时。时间单位:秒。即服务端 9 秒收不到客户端心跳,会将该客户端注册的实例删除:
配置文件示例
spring: application: name: nacos-producer cloud: nacos: discovery: server-addr: 10.7.11.13:8848 metadata: preserved.heart.beat.interval: 1000 #心跳间隔。时间单位:秒。心跳间隔 preserved.heart.beat.timeout: 3000 #心跳暂停。时间单位:秒。 即服务端6秒收不到客户端心跳,会将该客户端注册的实例设为不健康: preserved.ip.delete.timeout: 3000 #Ip删除超时。时间单位:秒。即服务端9秒收不到客户端心跳,会将该客户端注册的实例删除:
复制代码
Nacos 控制台
舒服了
🍎QQ 群【837324215】
🍎关注我的公众号【Java 大厂面试官】,一起学习呗🍎🍎🍎
🍎个人 vx【lakernote】
评论