自动注册源码流程图
自动注册源码
1 自动装配
1.1 spring boot自动配置
引入spring-cloud-starter-alibaba-nacos-discovery-2.2.5.RELEASE.jar时
jar中META-INF/spring.factories文件
根据spring boot自动装配原则,会加载EnableAutoConfiguration对应的类
NacosServiceRegistryAutoConfiguration对应自动注册服务
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\
com.alibaba.cloud.nacos.ribbon.RibbonNacosAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\
com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,\
com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration,\
com.alibaba.cloud.nacos.NacosServiceAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration
1.2 NacosServiceRegistryAutoConfiguration
配置类中,自动向spring容器注入bean(NacosAutoServiceRegistration )
@Bean
@ConditionalOnBean({AutoServiceRegistrationProperties.class})
public NacosAutoServiceRegistration nacosAutoServiceRegistration(NacosServiceRegistry registry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, NacosRegistration registration) {
return new NacosAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration);
}
1.3 NacosAutoServiceRegistration
继承自AbstractAutoServiceRegistration
AbstractAutoServiceRegistration又实现了ApplicationListener<WebServerInitializedEvent>
项目启动时会触发onApplicationEvent
最终调用本类的this.register()的方法实现注册服务
public void onApplicationEvent(WebServerInitializedEvent event) {
this.bind(event);
}
public void bind(WebServerInitializedEvent event) {
ApplicationContext context = event.getApplicationContext();
if (!(context instanceof ConfigurableWebServerApplicationContext) || !"management".equals(((ConfigurableWebServerApplicationContext)context).getServerNamespace())) {
this.port.compareAndSet(0, event.getWebServer().getPort());
this.start();
}
}
public void start() {
if (!this.isEnabled()) {
} else {
if (!this.running.get()) {
this.context.publishEvent(new InstancePreRegisteredEvent(this, this.getRegistration()));
//注册服务
this.register();
if (this.shouldRegisterManagement()) {
this.registerManagement();
}
this.context.publishEvent(new InstanceRegisteredEvent(this, this.getConfiguration()));
this.running.compareAndSet(false, true);
}
}
}
protected void register() {
this.serviceRegistry.register(this.getRegistration());
}
1.4 serviceRegistry.register
public void register(Registration registration) {
if (StringUtils.isEmpty(registration.getServiceId())) {
} else {
NamingService namingService = this.namingService();
String serviceId = registration.getServiceId();
String group = this.nacosDiscoveryProperties.getGroup();
//构建instance实例
Instance instance = this.getNacosInstanceFromRegistration(registration);
try {
//向服务端注册此服务
namingService.registerInstance(serviceId, group, instance);
} catch (Exception var7) {
ReflectionUtils.rethrowRuntimeException(var7);
}
}
}
1.5 namingService.registerInstance
@Override
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
NamingUtils.checkInstanceIsLegal(instance);
//注册服务(2.0.0默认grpc)
clientProxy.registerService(serviceName, groupName, instance);
}
1.6 clientProxy
clientProxy接口实现类如下图
2.0.0以后默认GRPC,2.0.0以前用HTTP
当前使用NamingGrpcClientProxy
2 grpc启动
2.1 NamingGrpcClientProxy构造函数
构造函数中,会创建rpcClient 对象
public NamingGrpcClientProxy(String namespaceId, SecurityProxy securityProxy, ServerListFactory serverListFactory,
Properties properties, ServiceInfoHolder serviceInfoHolder) throws NacosException {
...
this.rpcClient = RpcClientFactory.createClient(uuid, ConnectionType.GRPC, labels);
...
start(serverListFactory, serviceInfoHolder);
}
private void start(ServerListFactory serverListFactory, ServiceInfoHolder serviceInfoHolder) throws NacosException {
rpcClient.serverListFactory(serverListFactory);
//连接服务器
rpcClient.start();
rpcClient.registerServerRequestHandler(new NamingPushRequestHandler(serviceInfoHolder));
rpcClient.registerConnectionListener(namingGrpcConnectionEventListener);
}
2.2 registerInstance方法
public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {
InstanceRequest request = new InstanceRequest(namespaceId, serviceName, groupName,
NamingRemoteConstants.REGISTER_INSTANCE, instance);
//发送请求
requestToServer(request, Response.class);
namingGrpcConnectionEventListener.cacheInstanceForRedo(serviceName, groupName, instance);
}
private <T extends Response> T requestToServer(AbstractNamingRequest request, Class<T> responseClass)
throws NacosException {
try {
request.putAllHeader(getSecurityHeaders());
request.putAllHeader(getSpasHeaders(
NamingUtils.getGroupedNameOptional(request.getServiceName(), request.getGroupName())));
//发送请求
Response response =
requestTimeout < 0 ? rpcClient.request(request) : rpcClient.request(request, requestTimeout);
if (ResponseCode.SUCCESS.getCode() != response.getResultCode()) {
throw new NacosException(response.getErrorCode(), response.getMessage());
}
if (responseClass.isAssignableFrom(response.getClass())) {
return (T) response;
}responseClass.getName());
} catch (Exception e) {
throw new NacosException(NacosException.SERVER_ERROR, "Request nacos server failed: ", e);
}
throw new NacosException(NacosException.SERVER_ERROR, "Server return invalid response");
}
2.3 rpcClient.request(request)
发送rpc请求,后面代码就不跟了