Springboot 集成 es cluster 以及一个 Bean 加载顺序问题

607 阅读1分钟

在开发时,es使用的是单node的es,而不是集群。现在准备部署正式环境了,那么如何在Springboot工程中集成es cluster呢?

首先查了一些博客,但是都写的似是而非(可能是因为版本问题,不同es的版本的差异比较大),然后我去查了官方文档,虽然现在的英文水平读原文还是有点吃力,但忍不住说一句,第一手信息是真香,能够干净利落地解决问题。

我现在用的是6.0版本,官方文档如是写道:

这个问题算是解决了,但是遇到了新的问题。

之前在ApplicationConfiguration.java类中通过@Value(${es.host})来读取这些属性,并在ApplicationConfiguration.java中通过@Bean来配置初始化esClient,然后通过profiles.active控制加载相应环境的properties。

现在的问题是,因为现在dev环境下只有一个es.host,prod环境下由于有多个node,所以会有多个es.host,host的placeholder数量不一样。

我的想法是运行时可以获取到当前环境的标记,然后通过这个标记的差异来区别加载esClient,那么需要再写一个ApplicationContextHelper类来获取一些运行时参数。

于是代码变成了这样:

@Configuration
@PropertySource("classpath:application.properties")
public class ApplicationConfiguration {

 @Value("${es.host1}")
 private String esHost1;

 @Value("${es.host2}")
 private String esHost2;

 @Value("${es.host3}")
 private String esHost3;

 @Value("${es.host4}")
 private String esHost4;

 @Value("${es.host5}")
 private String esHost5;

 @Value("${es.port}")
 private Integer esPort;

 @Bean
 public RestHighLevelClient esClient() {
   RestClientBuilder builder = null;
   if ("prod".equals(ApplicationContextHelper.getActiveProfile())) {
      builder = RestClient.builder(
       new HttpHost(esHost1, esPort, "http"),
       new HttpHost(esHost2, esPort, "http"),
       new HttpHost(esHost3, esPort, "http"),
       new HttpHost(esHost4, esPort, "http"),
       new HttpHost(esHost5, esPort, "http"));
   } else if ("dev".equals(ApplicationContextHelper.getActiveProfile())){
      builder = RestClient.builder(new HttpHost(esHost1, esPort, "http"));
   }
   return new RestHighLevelClient(builder);
 }
 }

但是调试时又出现了新的问题,因为这个类依赖于ApplicationContextHelper,而Spring加载Bean的顺序默认是随机的,假如ApplicationConfigurationApplicationContextHelper之前加载的话,将会出现NPE。于是我想控制Bean的加载循序,查了文档后,在ApplicationConfiguration上加了@DependsOn("applicationContextHelper")注解,这样就能优先加载applicationContextHelper到Spring了。

这样问题就解决了。