前言
问题现象
排查
其实很容易想到,这是默认心跳超时配置以及剔除策略配置导致的,然后各种 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】
评论