作为SpringCloudAlibaba微服务架构实战派上下册和RocketMQ消息中间件实战派上下册的作者胡弦,我来给大家带来Nacos源码分析的技术文章。
Nacos默认会启动两个gRPC服务端通信渠道,一个用于Nacos集群节点之间的交互(GrpcClusterServer),另外一个用于客户端与Nacos服务器之间的交互(GrpcSdkServer)。这个也满足架构设计中的隔离原则,也就是客户端(特指接入Nacos中的服务实例)和Nacos集群自身是解耦合的。
 public static final Integer SDK_GRPC_PORT_DEFAULT_OFFSET = 1000;
    
 public static final Integer CLUSTER_GRPC_PORT_DEFAULT_OFFSET = 1001;利用Java的注解@PostConstruct自动地启动
其实很简单,Nacos就是利用Java的注解 @PostConstruct来自动地启动,关于这个注解@PostConstruct这里可以简单的解释一下。
/**
 * 用于标记方法的注解,该方法将在一个Bean实例化后,但在其被实际使用前调用。
 * 这使得开发者能够执行一些初始化逻辑,而无需手动管理对象的生命周期。
 * 
 * @author Java平台
 * @since Java EE 5.0
 */
public @interface PostConstruct {
}Nacos用注解@PostConstruct来标记抽象类BaseRpcServer的方法start()。
/**
 * 在服务器构建之后立即调用此方法,用于启动RPC服务器。
 * 该方法不接受参数且没有返回值。
 * 启动过程中,首先记录启动日志,然后启动服务器本身,接着如果存在SSL上下文刷新器,则刷新SSL上下文。
 * 最后,注册一个关闭钩子,以便在应用程序关闭时能够优雅地停止RPC服务器。
 * 
 * @throws Exception 如果启动过程中遇到任何错误,则抛出异常。
 */
@PostConstruct
public void start() throws Exception {
    String serverName = getClass().getSimpleName();
    // 记录启动日志
    Loggers.REMOTE.info("Nacos {} Rpc server starting at port {}", serverName, getServicePort());
    
    startServer();
    
    // 如果存在SSL上下文刷新器,则刷新SSL上下文
    if (RpcServerSslContextRefresherHolder.getInstance() != null) {
        RpcServerSslContextRefresherHolder.getInstance().refresh(this);
    }
    
    // 记录启动成功日志
    Loggers.REMOTE.info("Nacos {} Rpc server started at port {}", serverName, getServicePort());
    // 注册关闭钩子,以优雅地停止服务器
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        // 记录停止日志
        Loggers.REMOTE.info("Nacos {} Rpc server stopping", serverName);
        try {
            // 停止服务器
            BaseRpcServer.this.stopServer();
            // 记录停止成功日志
            Loggers.REMOTE.info("Nacos {} Rpc server stopped successfully...", serverName);
        } catch (Exception e) {
            // 记录停止失败日志
            Loggers.REMOTE.error("Nacos {} Rpc server stopped fail...", serverName, e);
        }
    }));
    
}抽象类BaseRpcServer的具体实现类如下图所示,分别是GrpcClusterServer和GrpcSdkServer。
 
 
其中BaseRpcServer的方法start()会调用BaseGrpcServer类的 startServer() 方法。
而GrpcClusterServer和GrpcSdkServer会使用Spring注解@Service完成Bean的初始化,这样就可以利用Java的注解 @PostConstruct来自动地启动这两个服务端通信渠道。
@Service
public class GrpcSdkServer extends BaseGrpcServer {
}@Service
public class GrpcClusterServer extends BaseGrpcServer {
}


![[C++初阶]类和对象(一)](https://img-blog.csdnimg.cn/direct/08f31fc8dcfb4c0795857214978b480d.png)















