springboot 注册服务注册中心(zk)的两种方式

 

在使用springboot进行开发的过程当中,咱们常常须要处理这样的场景:在服务启动的时候,须要向服务注册中心(例如zk)注册服务状态,以便当服务状态改变的时候,能够故障摘除和负载均衡。web

我遇到过两种注册的途径:spring

一、在Spring的webapplication启动完成后,直接进行注册;springboot

二、在servlet容器启动完成后,经过listener进行注册。app

本文经过一个demo讲述一下这两种注册方式,使用的是传统的向zk注册的方案。负载均衡

 

一、Spring webapplication启动完成后注册webapp

先上代码看一下ide

@SpringBootApplication public class WebApplication { private static final Logger logger = LoggerFactory.getLogger(WebApplication.class); private static volatile boolean IS_REGISTRY = false; public static void main(String[] args) { ApplicationContext context = run(WebApplication.class, args); if (IS_REGISTRY) { logger.info("注册2: WebApplication启动完成后"); ZkClient zkClient = context.getBean(ZkClient.class); zkClient.register(); IS_REGISTRY = true; logger.info("注册2: 注册成功"); } } }

这里,咱们在WebApplication中,获取zkClient,并进行注册。this

这里须要说明一点,咱们这里经过ApplicationContext来获取zkClient的bean,缘由是在webApplication的初始化过程当中你不能用Autowired的方式注入Bean,由于在webApplication启动过程当中才会读全部的configuration并将bean初始化完成,在没有完成初始化以前,你不能注入bean。spa

关于注册的详细代码这里不展开了。code

 

二、在servlet容器初始化完成后,经过listener的方式进行注册

照样先上代码

@WebListener public class RegisterListener implements ServletContextListener { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); private static volatile boolean IS_REGISTRY = false; @Autowired private ZkClient zkClient; @Override public void contextInitialized(ServletContextEvent servletContextEvent) { try { if (!IS_REGISTRY) { logger.info("注册1: Servelet容器启动成功后");
 zkClient.register(); logger.info("注册1: 注册成功"); } IS_REGISTRY = true; } catch (Exception e) { IS_REGISTRY = false; logger.info("注册1: 注册失败"); } } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { if (IS_REGISTRY) { zkClient.stop(); } } }

你须要先写一个listener,这个listener实现ServletContextListener接口,而且用@WebListener进行注解,这是springboot注解式的listener书写方式。

在servlet容器启动成功以后,会调用这个监听器的contextInitialized方法,servlet容器若是一旦销毁,不能提供服务了,会调用监听器的contextDestroyed方法。换句话说,这个监听器在监听servlet容器的状态。

而后你只须要在application主类中打开listener配置就好。

@ServletComponentScan @SpringBootApplication public class WebApplication { }

 

三、这两种方式的比较

对于一个对外提供http协议的web服务,在语义上servlet容器的注册会显得清晰一些,可是若是你的spring容器启动时间过长的话,可能出现servlet初始化完成,而且已经注册,可是服务不能对外提供访问的gap time,因此我通常仍是使用第一种方式进行注册。

这种场景是这样的

能够看到,当servlet注册成功以后,其实webapplication尚未启动完成,这个时候服务是不能正常提供访问的。

在zk上能够看到,两次注册都已经成功了。

相关文章
相关标签/搜索