【Nacos服务的发现和订阅总结】

介绍Nacos发现和订阅

服务发现

在这里插入图片描述

服务发现是指 服务提供者(Provider)自动注册到 Nacos,服务消费者(Consumer)可以通过 Nacos 获取最新的服务实例列表,实现动态调用。
Nacos 服务发现流程
1.服务提供者注册启动时,将自己的信息(IP、端口、元数据等)注册到 Nacos。
2.Nacos 维护服务实例,Nacos 维护一个服务实例列表,并定期进行健康检查。
3.服务消费者发现,消费者从 Nacos 获取可用实例列表,调用合适的实例。

服务订阅

服务订阅是指服务消费者主动监听服务实例的变化,如果实例下线、健康状态改变,Nacos 会主动推送最新的服务实例列表,而不是消费者自己轮询查询。
订阅的优势,实时感知服务变更,降低网络流量消耗(相比轮询方式),提高系统可用性,避免调用下线服务。
Nacos 订阅的底层机制:
1.消费者向 Nacos 注册监听器,通过 subscribe() 方法注册监听服务变更事件。
2.Nacos 维护长连接,采用 UDP / gRPC 长连接,实时推送服务变更。
3.Nacos 发现服务变更,主动推送当实例新增 / 下线 / 宕机,Nacos 立即通知所有订阅的消费者。
4.消费者更新本地缓存,消费者用最新的实例列表替换本地缓存,避免调用已下线的实例。

服务发现代码分析

服务发现的代码逻辑主要在Nacos客户端,我们首先从META-INF的spring.factory文件中找到NacosDiscoveryClientConfiguration这个类。
在这里插入图片描述
我们找到NacosDiscoveryClient的源码进行分析

//获取实例信息
public List<ServiceInstance> getInstances(String serviceId) {
        try {
            return (List)Optional.of(this.serviceDiscovery.getInstances(serviceId)).map((instances) -> {
                ServiceCache.setInstances(serviceId, instances);
                return instances;
            }).get();
        } catch (Exception var3) {
            if (this.failureToleranceEnabled) {
                return ServiceCache.getInstances(serviceId);
            } else {
                throw new RuntimeException("Can not get hosts from nacos server. serviceId: " + serviceId, var3);
            }
        }
    }
	//获取nacos上的服务信息
    public List<String> getServices() {
        try {
            return (List)Optional.of(this.serviceDiscovery.getServices()).map((services) -> {
                ServiceCache.setServiceIds(services);
                return services;
            }).get();
        } catch (Exception var2) {
            log.error("get service name from nacos server failed.", var2);
            return this.failureToleranceEnabled ? ServiceCache.getServiceIds() : Collections.emptyList();
        }
    }

在这里插入图片描述

手动实现服务的发现

@RestController
@RequestMapping("/query")
public class Controller {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/services")
    public List<String> getServices() {
        return discoveryClient.getServices();  // 获取所有注册的服务
    }

    @GetMapping("/instances")
    public List<ServiceInstance> getInstances() {
        return discoveryClient.getInstances("service-provider");  // 获取某个服务的所有实例
    }
}

服务的订阅实现

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>2.2.3</version>
</dependency>

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.listener.InstanceEvent;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;

@Component
public class NacosServiceSubscriber {

    private NamingService namingService;

    @PostConstruct
    public void init() throws Exception {
        // 连接 Nacos 服务器
        namingService = NacosFactory.createNamingService("127.0.0.1:8848");

        // 订阅 service-provider 的变化
        namingService.subscribe("service-provider", event -> {
            if (event instanceof InstanceEvent) {
                List<Instance> instances = namingService.getAllInstances("service-provider");
                System.out.println("service-provider 发生变化,当前实例:" + instances);
            }
        });
    }
}

订阅服务的比较
Spring Cloud DiscoveryClient Spring Cloud 项目 discoveryClient.getInstances() 简单易用。
Nacos SDK NamingService.subscribe() 更细粒度的监听 NamingService.subscribe() 主动监听,实时响应
Nacos OpenAPI 非 Java 语言、第三方服务 调用 HTTP API 轮询方式,可能有延迟

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值