SpringCloudAlibaba Nacos1.4.1原理分析(注册,发现,配置中心)

服务注册:
先说原理逻辑:就是一个http请求,然后交给nacos服务端,服务端采用了异步任务+阻塞队列的形式,提升了高并发的处理。
Nacos客户端:首先我们在服务中引用nacos-discovery依赖,当我们启动项目时,nacos会根据事件发布的机制,

public abstract class AbstractAutoServiceRegistration<R extends Registration>
		implements AutoServiceRegistration, ApplicationContextAware,
		ApplicationListener<WebServerInitializedEvent> {
		//省略部分
	@Override
	@SuppressWarnings("deprecation")
	//事件监听,由spring自动触发。
	public void onApplicationEvent(WebServerInitializedEvent event) {
		bind(event);
	}
	//事件处理
	@Deprecated
	public void bind(WebServerInitializedEvent event) {
		//省略部分
		this.start();
	}

	public void start() {
		if (!isEnabled()) {
			if (logger.isDebugEnabled()) {
				logger.debug("Discovery Lifecycle disabled. Not starting");
			}
			return;
		}
		if (!this.running.get()) {
			this.context.publishEvent(
					new InstancePreRegisteredEvent(this, getRegistration()));
					//服务注册核心
			register();
			if (shouldRegisterManagement()) {
				registerManagement();
			}
			this.context.publishEvent(
					new InstanceRegisteredEvent<>(this, getConfiguration()));
			this.running.compareAndSet(false, true);
		}

	}
		protected void register() {
		//服务注册
		this.serviceRegistry.register(getRegistration());
	}

NacosServiceRegistry

	@Override
	public void register(Registration registration) {

		if (StringUtils.isEmpty(registration.getServiceId())) {
			log.warn("No service to register for nacos client...");
			return;
		}
		//获取配置信息
		NamingService namingService = namingService();
		String serviceId = registration.getServiceId();
		String group = nacosDiscoveryProperties.getGroup();

		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) {
			log.error("nacos registry, {} register failed...{},", serviceId,
					registration.toString(), e);
			// rethrow a RuntimeException if the registration is failed.
			// issue : https://github.com/alibaba/spring-cloud-alibaba/issues/1132
			rethrowRuntimeException(e);
		}
	}

NacosNamingService

    @Override
    public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
        NamingUtils.checkInstanceIsLegal(instance);
        String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
        if (instance.isEphemeral()) {
        //发送心跳检查(先不看),我们先看注册逻辑
            BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
            beatReactor.addBeatInfo(groupedServiceName, beatInfo);
        }
        //注册核心这里
        serverProxy.registerService(groupedServiceName, groupName, instance);
    }

NamingProxy实际上就是一个http的请求:请求路径为:"/nacos/v1/ns/instance"

    public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {
        
        NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}", namespaceId, serviceName,
                instance);
        //这些就是你配置文件里面的东西,配置类请看下面
        final Map<String, String> params = new HashMap<String, String>(16);
        params.put(CommonParams.NAMESPACE_ID, namespaceId);
        params.put(CommonParams.SERVICE_NAME, serviceName);
        params.put(CommonParams.GROUP_NAME, groupName);
        params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
        params.put("ip", instance.getIp());
        params.put("port", String.valueOf(instance.getPort()));
        params.put("weight", String.valueOf(instance.getWeight()));
        params.put("enable", String.valueOf(instance.isEnabled()));
        params.put("healthy", String.valueOf(instance.isHealthy()));
        params.put("ephemeral", String.valueOf(instance.isEphemeral()));
        params.put("metadata", JacksonUtils.toJson(instance.getMetadata()));
        //注册核心。就是一个http请求。就是你nacos服务端的地址+端口+"/nacos/v1/ns/instance"
        reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.POST); 
    }
    上面参数路径为:UtilAndComs.nacosUrlInstance = "/nacos/v1/ns/instance"

官方文档:
在这里插入图片描述

你的yml配置文件中的spring.cloud.nacos.discovery

@ConfigurationProperties("spring.cloud.nacos.discovery")
public class NacosDiscoveryProperties {

	private static final Logger log = LoggerFactory
			.getLogger(NacosDiscoveryProperties.class);

	/**
	 * Prefix of {@link NacosDiscoveryProperties}.
	 */
	public static final String PREFIX = "spring.cloud.nacos.discovery";

	private static final Pattern PATTERN = Pattern.compile("-(\\w)");
	
	你nacos的地址
	/**
	 * nacos discovery server address. 
	 */
	private String serverAddr;

	/**
	 * the nacos authentication username.
	 */
	private String username;

	/**
	 * the nacos authentication password.
	 */
	private String password;

	/**
	 * the domain name of a service, through which the server address can be dynamically
	 * obtained.
	 */
	private String endpoint;

	/**
	 * namespace, separation registry of different environments.
	 */
	private String namespace;

	/**
	 * watch delay,duration to pull new service from nacos server.
	 */
	private long watchDelay = 30000;

	/**
	 * nacos naming log file name.
	 */
	private String logName;

	/**
	 * service name to registry.
	 */
	@Value("${spring.cloud.nacos.discovery.service:${spring.application.name:}}")
	private String service;

	/**
	 * weight for service instance, the larger the value, the larger the weight.
	 */
	private float weight = 1;

	/**
	 * cluster name for nacos .
	 */
	private String clusterName = "DEFAULT";

	/**
	 * group name for nacos.
	 */
	private String group = "DEFAULT_GROUP";

	/**
	 * naming load from local cache at application start. true is load.
	 */
	private String namingLoadCacheAtStart = "false";

	/**
	 * extra metadata to register.
	 */
	private Map<String, String> metadata = new HashMap<>();

	/**
	 * if you just want to subscribe, but don't want to register your service, set it to
	 * false.
	 */
	private boolean registerEnabled = true;

	/**
	 * The ip address your want to register for your service instance, needn't to set it
	 * if the auto detect ip works well.
	 */
	private String ip;

	/**
	 * which network interface's ip you want to register.
	 */
	private String networkInterface = "";

	/**
	 * The port your want to register for your service instance, needn't to set it if the
	 * auto detect port works well.
	 */
	private int port = -1;

	/**
	 * whether your service is a https service.
	 */
	private boolean secure = false;

	/**
	 * access key for namespace.
	 */
	private String accessKey;

	/**
	 * secret key for namespace.
	 */
	private String secretKey;

	/**
	 * Heart beat interval. Time unit: millisecond.
	 */
	private Integer heartBeatInterval;

	/**
	 * Heart beat timeout. Time unit: millisecond.
	 */
	private Integer heartBeatTimeout;

	/**
	 * Ip delete timeout. Time unit: millisecond.
	 */
	private Integer ipDeleteTimeout;

	/**
	 * If instance is enabled to accept request. The default value is true.
	 */
	private boolean instanceEnabled = true;

	/**
	 * If instance is ephemeral.The default value is true.
	 */
	private boolean ephemeral = true;

然后你的nacos服务端就有一个接口去接收上面的这个请求

@RestController
@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/instance")
public class InstanceController {
    //省略部分
    
 //服务注册在这个方法里面。实现方式:异步任务+阻塞队列
    @CanDistro
    @PostMapping
    @Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
    public String register(HttpServletRequest request) throws Exception {
        
        final String namespaceId = WebUtils
                .optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
        final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
        NamingUtils.checkServiceNameFormat(serviceName);
        
        final Instance instance = parseInstance(request);
        //真正的处理客户端的注册。
        serviceManager.registerInstance(namespaceId, serviceName, instance);
        return "ok";
    }
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值