Consul 注册发现

214 阅读1分钟

1. 注册

ConsulAutoServiceRegistration继承自AbstractAutoServiceRegistration AbstractAutoServiceRegistration是服务注册的抽象方法,属于spring-cloud-commons,基于它可以实现自己的服务注册。 AbstractAutoServiceRegistration实现了ApplicationListener接口,在spring启动以后, onApplicationEvent -> bind(event) -> start(),在start方法内进行register操作。

public abstract class AbstractAutoServiceRegistration<R extends Registration>
		implements AutoServiceRegistration, ApplicationContextAware,
		ApplicationListener<WebServerInitializedEvent> {
	//code removed
	
	@Override
	@SuppressWarnings("deprecation")
	public void onApplicationEvent(WebServerInitializedEvent event) {
		bind(event);
	}

	@Deprecated
	public void bind(WebServerInitializedEvent event) {
		ApplicationContext context = event.getApplicationContext();
		//code removed
		this.port.compareAndSet(0, event.getWebServer().getPort());
		this.start();
	}

	public void start() {
		if (!isEnabled()) {
			if (logger.isDebugEnabled()) {
				logger.debug("Discovery Lifecycle disabled. Not starting");
			}
			return;
		}

		// only initialize if nonSecurePort is greater than 0 and it isn't already running
		// because of containerPortInitializer below
		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());
	}
    protected void deregister() {
		this.serviceRegistry.deregister(getRegistration());
	}

Consul做的事情就是实现了ConsulRegistration和ConsulServiceRegistry

ConsulServiceRegistry中的register方法如下

  1. client.agentServiceRegister向consul服务器注册
  2. 开启心跳scheduler
@Override
	public void register(ConsulRegistration reg) {
		log.info("Registering service with consul: " + reg.getService());
		try {
			this.client.agentServiceRegister(reg.getService(),
					this.properties.getAclToken());
			NewService service = reg.getService();
			if (this.heartbeatProperties.isEnabled() && this.ttlScheduler != null
					&& service.getCheck() != null
					&& service.getCheck().getTtl() != null) {
				this.ttlScheduler.add(reg.getInstanceId());
			}
		}
		catch (ConsulException e) {
			if (this.properties.isFailFast()) {
				log.error("Error registering service with consul: " + reg.getService(),
						e);
				ReflectionUtils.rethrowRuntimeException(e);
			}
			log.warn("Failfast is false. Error registering service with consul: "
					+ reg.getService(), e);
		}
	}

deregister方法

  1. 移除心跳scheduler
  2. 调用client发起deregister请求
	@Override
	public void deregister(ConsulRegistration reg) {
		if (this.ttlScheduler != null) {
			this.ttlScheduler.remove(reg.getInstanceId());
		}
		if (log.isInfoEnabled()) {
			log.info("Deregistering service with consul: " + reg.getInstanceId());
		}
		this.client.agentServiceDeregister(reg.getInstanceId(),
				this.properties.getAclToken());
	}