设为首页 加入收藏

TOP

Nacos源码 (3) 注册中心(一)
2023-08-26 21:11:08 】 浏览:127
Tags:Nacos 源码

本文将从一个服务注册示例入手,通过阅读客户端、服务端源码,分析服务注册、服务发现原理。

使用的2.0.2的版本。

客户端

创建NacosNamingService对象

NacosNamingService nacosNamingService = new NacosNamingService(NACOS_HOST);

NacosNamingService提供两个构造方法:

public NacosNamingService(String serverList) throws NacosException {
    Properties properties = new Properties();
    properties.setProperty(PropertyKeyConst.SERVER_ADDR, serverList);
    init(properties);
}

public NacosNamingService(Properties properties) throws NacosException {
    init(properties);
}

第二个方法的properties的key在PropertyKeyConst常量类可以找到,如:

  • namespace
  • username
  • password
  • serverAddr
  • clusterName
  • 其他

构造方法中会初始化一些参数和组件:

  • 初始化namespace参数

  • 创建InstancesChangeNotifier对象,它实现了Subscriber接口,监听InstancesChangeEvent事件

    public class InstancesChangeNotifier extends Subscriber<InstancesChangeEvent> {
    
        // key使用serviceName + groupName + clusters组合而成
        // value是监听器集合
        private final Map<String, ConcurrentHashSet<EventListener>> listenerMap;
    
        // 锁
        private final Object lock = new Object();
    
  • 向NotifyCenter注册InstancesChangeEvent事件,注册之前创建的InstancesChangeNotifier对象监听服务实例变化

    NotifyCenter.registerToPublisher(InstancesChangeEvent.class, 16384);
    NotifyCenter.registerSubscriber(changeNotifier);
    
    // NotifyCenter维护着EventPublisher集,Subscriber会被注册到EventPublisher上
    // EventPublisher提供publish方法向Event队列推送事件
    // EventPublisher是一个Thread类,run方法从Event队列取事件通知Subscriber来处理
    
  • 创建NamingClientProxyDelegate对象,用于与服务端通信,它是一个代理,内部使用其他的NamingClientProxy实现:

    • NamingHttpClientProxy
    • NamingGrpcClientProxy - 默认使用该实现类,其中有healthCheck检测服务端是否健康,服务端直接响应成功无操作

服务注册

NacosNamingService nacosNamingService = new NacosNamingService(NACOS_HOST);
nacosNamingService.registerInstance(ORDER_SERVICE, "192.168.0.100", 9999);

提供多个重载的registerInstance方法,最终使用这个方法:

public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName)
            throws NacosException {
    Instance instance = new Instance();
    instance.setIp(ip);
    instance.setPort(port);
    instance.setWeight(1.0);
    instance.setClusterName(clusterName);
    registerInstance(serviceName, groupName, instance);
}

public void registerInstance(String serviceName, String groupName, Instance instance)
            throws NacosException {
    // 此处clientProxy是NamingClientProxyDelegate对象
    clientProxy.registerService(serviceName, groupName, instance);
}

NamingClientProxyDelegate的registerService方法会选择一个具体的NamingClientProxy对象与服务端通信,默认使用NamingGrpcClientProxy对象。

NamingGrpcClientProxy的registerService方法构建InstanceRequest请求对象,之后使用RpcClient对象发送请求并接收响应。

RpcClient内部通过GrpcConnection对象使用GRPC来访问服务端。

内部的GRPC代码是使用protoc和protobuf-maven-plugin生成的,通信细节此处不做介绍。

服务下线

nacosNamingService.deregisterInstance(ORDER_SERVICE, "192.168.0.100", 9999);

deregisterInstance服务下线:

public void deregisterInstance(String serviceName,
                               String groupName,
                               String ip,
                               int port,
                               String clusterName) throws NacosException {
    Instance instance = new Instance();
    instance.setIp(ip);
    instance.setPort(port);
    instance.setClusterName(clusterName);
    deregisterInstance(serviceName, groupName, instance);
}

public void deregisterInstance(String serviceName,
                               String groupName,
                               Instance instance) throws NacosException {
    clientProxy.deregiste
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/9/9
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇quarkus数据库篇之一:比官方demo.. 下一篇JDK 17 营销初体验 —— 亚毫秒停..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目