Nacos注册中心与配置中心

zhangliangddq / 2023-08-22 / 原文

Nacos中文官网

https://nacos.io/zh-cn/docs/v2/quickstart/quick-start.html

注册中心(客户端pull和服务端push)

1. NacosServiceRegistryAutoConfiguration 加载Start
2. 加载配置 并发布事件:NacosDiscoveryInfoChangedEvent
3. 注入NacosAutoServiceRegistration 并监听事件NacosDiscoveryInfoChangedEvent
4. 调用start方法
5. NacosServiceRegistry.register() 具体的实现类.方法
6. NacosNamingService.registerInstance()
7. 先开启定时任务 去定时刷新心跳 再去注册 默认情况下: 5秒上报一次心跳
8. 注册完成后 服务中心会将服务变动通知给客户端 采用UDP通信 例如:new ips(1) service
9. clien注册时 ephemeral=true 采用的是AP模式 即服务端集群中只要有一个注册成功则返回 不用等待所有都更新成功。
10. 第一次会携带beat信息 剩下的不会携带beat信息

ephemeral

nacos 目前的instance有一个ephemeral字段属性,该字段表示实例是否是临时实例还是持久化实例。如果是临时实例则不会在nacos中持久化,需要通过心跳上报,如果一段时间没有上报心跳,则会被nacos服务端删除。删除后如果又重新开始上报,则会重新实例注册。而持久化实例会被nacos服务端持久化,此时即使注册实例的进程不存在,这个实例也不会删除,只会将健康状态设置成不健康。 临时:true 持久化:false

心跳机制

  1. 客户端上报模式:客户端通过心跳上报的方式告知nacos 注册中心健康状态(默认心跳间隔5s,nacos将超过15s未收到心跳的实例设置为不健康(不会发送通知),超过30s将实例删除)。

服务端健康检查

 @PutMapping("/beat")
int resultCode = getInstanceOperator()
             .handleBeat(namespaceId, serviceName, ip, port, clusterName, clientBeat, builder);
//处理心跳的逻辑
@Override
 public int handleBeat(String namespaceId, String serviceName, String ip, int port, String cluster,
         RsInfo clientBeat, BeatInfoInstanceBuilder builder) throws NacosException {
     Service service = getService(namespaceId, serviceName, true);
     String clientId = IpPortBasedClient.getClientId(ip + InternetAddressUtil.IP_PORT_SPLITER + port, true);
     IpPortBasedClient client = (IpPortBasedClient) clientManager.getClient(clientId);
     if (null == client || !client.getAllPublishedService().contains(service)) {
         if (null == clientBeat) {
             return NamingResponseCode.RESOURCE_NOT_FOUND;
         }
         Instance instance = builder.setBeatInfo(clientBeat).setServiceName(serviceName).build();
         registerInstance(namespaceId, serviceName, instance);
         client = (IpPortBasedClient) clientManager.getClient(clientId);
     }
     if (!ServiceManager.getInstance().containSingleton(service)) {
         throw new NacosException(NacosException.SERVER_ERROR,
                 "service not found: " + serviceName + "@" + namespaceId);
     }
     if (null == clientBeat) {
         clientBeat = new RsInfo();
         clientBeat.setIp(ip);
         clientBeat.setPort(port);
         clientBeat.setCluster(cluster);
         clientBeat.setServiceName(serviceName);
     }

     //定时任务处理
     ClientBeatProcessorV2 beatProcessor = new ClientBeatProcessorV2(namespaceId, clientBeat, client);
     HealthCheckReactor.scheduleNow(beatProcessor);
     client.setLastUpdatedTime();
     return NamingResponseCode.OK;
 }

具体执行:ClientBeatProcessorV2.run();

nacos自我保护机制

https://blog.csdn.net/why_2012_gogo/article/details/126077894
自我保护机制(保护阈值0):Nacos为每个服务提供了保护阀值,其值范围在0-1之间,当服务实例健康个数占比(健康实例个数/总实例个数)小于这个保护阀值时,为降低服务雪崩的可能,也会向不健康实例发送请求,虽然牺牲了部分请求,但也起到了均摊流量的作用,避免整体系统无法提供服务的风险,这是值得的,这个阀值可在nacos ui后台手动设定