前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解决 Spring Cloud Consul 在 Tomcat 容器中服务注册问题

解决 Spring Cloud Consul 在 Tomcat 容器中服务注册问题

作者头像
斯武丶风晴
发布2020-04-24 18:17:51
9690
发布2020-04-24 18:17:51
举报
文章被收录于专栏:龙首琴剑庐龙首琴剑庐

问题

Spring Cloud Consul 2.1.x 在 Tomcat 容器中没有注册服务,但是在本地开发的时候是没问题的。

分析

Spring Cloud 2.1.x 注册服务, 是通过发布org.springframework.boot.web.context.WebServerInitializedEvent 事件实现的, 参考 org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationListener

  • org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationListener
代码语言:javascript
复制
@Override
	public void onApplicationEvent(ApplicationEvent applicationEvent) {
		if (applicationEvent instanceof WebServerInitializedEvent) {
			WebServerInitializedEvent event = (WebServerInitializedEvent) applicationEvent;

			ApplicationContext context = event.getApplicationContext();
			if (context instanceof ConfigurableWebServerApplicationContext) {
				if ("management".equals(
						((ConfigurableWebServerApplicationContext) context).getServerNamespace())) {
					return;
				}
			}
			this.autoServiceRegistration.setPortIfNeeded(event.getWebServer().getPort());
			this.autoServiceRegistration.start();
		}
	}

该事件仅在内嵌 Tomcat 中生效,参考 org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext, 而通过 Tomcat 容器启动服务时监听不到该事件。

  • org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext
代码语言:javascript
复制
  protected void finishRefresh() {
    super.finishRefresh();
    WebServer webServer = this.startWebServer();
	 // 这里在 内嵌Tomcat 启动后,webServer 不为 null ,发布 ServletWebServerInitializedEvent 事件,触发 ConsulAutoServiceRegistrationListener 注册服务
	// 这里在 Tomcat 容器启动服务 后,webServer 是 null 的,因此导致 ConsulAutoServiceRegistrationListener 接收不到对应的事件,从而无法服务注册
    if (webServer != null) {
      this.publishEvent(new ServletWebServerInitializedEvent(webServer, this));
    }
  }

解决

增加一个 ApplicationListener 监听 ApplicationReadyEvent, 在应用启动准备好后注册服务。 逻辑参考 org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationListener

代码语言:javascript
复制
import lombok.RequiredArgsConstructor;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.consul.ConditionalOnConsulEnabled;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistration;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * Spring Cloud 2.1 注册服务, 通过发布 {@link org.springframework.boot.web.context.WebServerInitializedEvent} 事件实现的, 参考 {@link
 * org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationListener}。
 *
 * <p>
 * 该事件仅在内嵌 Tomcat 中生效,参考 {@link org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext}, 而通过
 * Tomcat 容器启动服务时监听不到该事件。
 * </p>
 *
 * @author Sven Augustus
 */
@Component
@ConditionalOnConsulEnabled
@RequiredArgsConstructor
public class ConsulAutoServiceRegistrationInitializerListener implements ApplicationListener<ApplicationReadyEvent> {

  private final ConsulAutoServiceRegistration consulAutoServiceRegistration;
  private final ConsulDiscoveryProperties properties;

  @Override
  public void onApplicationEvent(ApplicationReadyEvent event) {
    consulAutoServiceRegistration.start();
  }

}

by Sven Augustus https://my.oschina.net/langxSpirit

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
    • 分析
      • 解决
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档