作为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 {
}