本文基于nacos-2.0.3版本

前面文章介绍了nacos的配置管理,从本文开始介绍nacos的服务注册与发现。
下面的网页详细介绍了如何基于spring cloud实现服务注册与发现:

https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html

通过上面网页的介绍,可以知道,nacos的服务注册最关键的是注解@EnableDiscoveryClient,本文接下来以该注解为起点,介绍服务注册原理。


本文目录

  • 1、@EnableDiscoveryClient
  • 2、EnableDiscoveryClientImportSelector
  • 3、AutoServiceRegistrationConfiguration
  • 4、NacosServiceRegistry


1、@EnableDiscoveryClient

EnableDiscoveryClient的代码很简单,引入了EnableDiscoveryClientImportSelector类,还有一个配置是否自动注册服务的属性,默认为true。

@Import(EnableDiscoveryClientImportSelector.class)
public @interface EnableDiscoveryClient {
	/**
	 * If true, the ServiceRegistry will automatically register the local server.
	 * @return - {@code true} if you want to automatically register.
	 */
	boolean autoRegister() default true;
}

接下来看一下EnableDiscoveryClientImportSelector类的原理。

2、EnableDiscoveryClientImportSelector

EnableDiscoveryClientImportSelector也比较简单,它检查了EnableDiscoveryClient的autoRegister属性值,如果是true,则引入AutoServiceRegistrationConfiguration类。

boolean autoRegister = attributes.getBoolean("autoRegister");
		if (autoRegister) {
			List<String> importsList = new ArrayList<>(Arrays.asList(imports));
			importsList.add(
					"org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration");
			imports = importsList.toArray(new String[0]);
		}
		else {
			Environment env = getEnvironment();
			if (ConfigurableEnvironment.class.isInstance(env)) {
				ConfigurableEnvironment configEnv = (ConfigurableEnvironment) env;
				LinkedHashMap<String, Object> map = new LinkedHashMap<>();
				map.put("spring.cloud.service-registry.auto-registration.enabled", false);
				MapPropertySource propertySource = new MapPropertySource(
						"springCloudDiscoveryClient", map);
				configEnv.getPropertySources().addLast(propertySource);
			}
		}

3、AutoServiceRegistrationConfiguration

AutoServiceRegistrationConfiguration类仅仅用于激活配置类AutoServiceRegistrationProperties。
AutoServiceRegistrationProperties用于配置服务是否自动注册等,配置的前缀是spring.cloud.service-registry.auto-registration

与配置相关的类还有一个是NacosDiscoveryProperties,该类用于配置nacos的基本信息,比如服务权重,服务名,服务地址,group,心跳间隔时间等,配置前缀是spring.cloud.nacos.discovery

4、NacosServiceRegistry

当web容器启动完毕后,会发布WebServerInitializedEvent事件。而NacosAutoServiceRegistration负责监听该事件。监听到事件后,将启动服务注册。服务注册调用NacosAutoServiceRegistration.register()方法。

NacosAutoServiceRegistration继承了抽象类AbstractAutoServiceRegistration,监听事件其实是这个抽象类做的,该抽象类提供了处理事件以及注册服务的方法,子类可以重写抽象类的方法,以完成特殊处理。

register()方法里面接着调用NacosServiceRegistry.register()方法。

NacosServiceRegistry负责注册/注销服务,设置或者查询服务状态是否正常。

下面是NacosServiceRegistry.register()方法的代码:

//Registration表示nacos服务端实例,保存了服务端的IP、端口、服务权重等
	public void register(Registration registration) {
		//代码删减
		//获取NamingService
		//NamingService相当于nacos的客户端
		NamingService namingService = namingService();
		//serviceId是应用名,可以使用spring.application.name或者spring.cloud.nacos.discovery.service指定
		String serviceId = registration.getServiceId();
		//默认是DEFAULT_GROUP
		String group = nacosDiscoveryProperties.getGroup();
		//创建nacos实例对象,代表了服务端实例
		Instance instance = getNacosInstanceFromRegistration(registration);

		try {
			//注册服务
			namingService.registerInstance(serviceId, group, instance);
			log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,
					instance.getIp(), instance.getPort());
		}
		catch (Exception e) {
			//代码删减
		}
	}

register()方法里面调用namingService对象向服务端注册服务。
namingService也就是NacosNamingService对象,NacosNamingService相当于nacos提供给应用程序使用的客户端,可以通过注解的方式在应用程序中直接获得实例。通过NacosNamingService可以完成对服务的管理。
NacosNamingService支持集群注册,如果配置了多个nacos服务器地址,NacosNamingService遍历每个地址,并向其注册服务,如果其中有一个没有注册成功,那么会调用该地址,继续向下一个地址注册。
NacosNamingService底层与配置管理一样,也是使用RESTful风格将数据发送到服务端。

注册服务的url地址为:
http://127.0.0.1:8848/nacos/v1/ns/instance/ 方法:POST