Spring Boot,Spring Cloud Alibaba 以及ElasticSearch的适配性问题分享

前言

本周为了开发一个日志相关的功能需要使用es,之前团队正好elk部署了一套就直接用了他们的es来调试,本来以为半天搞定的事,却遇到了版本适配的问题,折腾了一天多。赶紧记下来,希望对大家有帮助。

前期准备

我们都知道spring体系对于版本是很讲究的,兼容性不是特别理想,而且升级相对费劲,于是先核实一下我们es的版本7.9.3,心理一沉,好新的版本,惴惴不安去官网把说明文档读了一圈,发现了下面这张图。
Spring Boot,Spring Cloud Alibaba 以及ElasticSearch的适配性问题分享_第1张图片

我的天,这个springboot需要2.4.x,spring data 要2020.0.0。而我们项目主框架springboot的版本是2.2.6瑟瑟发抖,但是要是直接把主框架的给升级了,同学们要是知道了估计要原地爆炸的。于是抱着赌一把的心态先不管springboot直接把 spring data elasticsearch的依赖换了。于是开始了今天的故事。

具体问题

直接无法启动问题

关键报错信息如下

11:28:31.936 nacos [main] ERROR o.s.boot.SpringApplication - Application run failed
java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataConfiguration$BaseConfiguration.entityMapper
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60)
	at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:184)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144)
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
	at com.zw.ump.log.LogApplication.main(LogApplication.java:12)
Caused by: java.lang.IllegalStateException: @ConditionalOnMissingBean did not specify a bean using type, name or annotation and the attempt to deduce the bean's type failed
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.validate(OnBeanCondition.java:479)
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.<init>(OnBeanCondition.java:428)
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:140)
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
	... 17 common frames omitted

我们观察到其中核心的一句话是Error processing condition on org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataConfiguration$BaseConfiguration.entityMapper at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60)

无法初始化es的entityMapper,这个应该Spring框架无法加载es的实体映射辅助类,因此可以判定是es与SpringBoot不兼容。

嗯,没办法了,只能升级springboot,不过主框架版本是绝对不能动的,那个牵连太广。模块化的好处就是自己的模块可以随便搞,于是我把对于主框架的依赖移除,转而把spring-boot-starter-parent天道parent中,于是我的这个子模块的springboot框架升级到了2.4.1。

我们都知道springcloud与springboot是紧密于是查官网得知springcloud需要2020版本,有一种不祥的预感,因为太新的版本往往意味着不兼容。只能硬上了,springcloud和springcloud-alibaba分别更新为2020和2.2.1.Release。

无法注册到nacos上问题

截止到目前我们更新了springboot,springcloud,springcloud-alibibaba到spring.io显示的最新版本,但心里还是很不安,因为都太新了,很容易有兼容性问题。

这一次貌似一切正常,但是启动成功后,我检查一下输出,发现了一丝诡异的现象,竟然提示spring.application.name为空,我再去nacos下查询一下服务在不在,却发现空空如野。就好像服务没有找到bootstrap.yaml这个文件,我核对一遍名字,没问题啊。

这个问题就没有上一个问题那么好解决了,我检查了一遍又一遍,还是一样的现象。正当要找人把ES的版本降下来的时候,没办法只能最后一搏,于是只能拿出绝招,从头建立一个空白的对照项目,逐步添加依赖,发现只要把SpringCloudAlibaba221加到SpringCloud2020.0.0中就会出现这个问题、

于是跑到官网一看https://spring.io/projects/spring-cloud-alibaba#overview,没有显示alibaba和cloud的兼容关系表,好难。于是只能转战万能的github去issue,果然有很多人有一样的问题。
Spring Boot,Spring Cloud Alibaba 以及ElasticSearch的适配性问题分享_第2张图片

翻看解决方案时,有一个网友提供了官方解决方案,https://juejin.cn/post/6911980096177995789,亲测有效。

正确配置

springboot 2.4.1

es 的依赖4.1.2

springcloud 2020.0.0

springcloud alibaba 2.2.3.RELEASE

es 的版本7.9.3


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.4.1version>
        <relativePath/> 
    parent>
    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <java.version>1.8java.version>
        <spring-cloud.version>2020.0.0spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.3.RELEASEspring-cloud-alibaba.version>
    properties>

    <groupId>com.zw.umpgroupId>
    <artifactId>xxxartifactId>
    <version>0.0.1-SNAPSHOTversion>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starterartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-loadbalancerartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-bootstrapartifactId>
        dependency>
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
        dependency>
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-cloud-starter-netflix-ribbonartifactId>
                    <groupId>org.springframework.cloudgroupId>
                exclusion>
            exclusions>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.10version>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.datagroupId>
            <artifactId>spring-data-elasticsearchartifactId>
            <version>4.1.2version>
        dependency>
    dependencies>
    <dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                <version>${spring-cloud-alibaba.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-compiler-pluginartifactId>
                <configuration>
                    <source>1.8source>
                    <target>1.8target>
                    <encoding>UTF-8encoding>
                configuration>
            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-resources-pluginartifactId>
                <version>3.0.1version>
                <executions>
                    <execution>
                        <id>copy-confid>
                        <phase>packagephase>
                        <goals>
                            <goal>copy-resourcesgoal>
                        goals>
                        <configuration>
                            <encoding>UTF-8encoding>
                            <outputDirectory>target/ext/confoutputDirectory>
                            <resources>
                                <resource>
                                    <directory>ext/confdirectory>
                                    <includes>
                                        <include>*include>
                                    includes>
                                    <filtering>truefiltering>
                                resource>
                            resources>
                        configuration>
                    execution>
                executions>
            plugin>
        plugins>
    build>
    <repositories>
        <repository>
            <id>spring-milestonesid>
            <name>Spring Milestonesname>
            <url>https://repo.spring.io/milestoneurl>
        repository>
    repositories>
project>

总结

  1. 更新版本一定要谨慎
  2. 官网更新也有延迟特别是springcloud alibaba这种,去github它的主页上才是最靠谱的
  3. 阿里的技术能力确实强,那个问题解决的很是漂亮。

参考资料

  • https://docs.spring.io/spring-data/elasticsearch/docs/4.1.2/reference/html/#new-features
  • https://juejin.cn/post/6911980096177995789
  • https://spring.io/projects/spring-cloud-alibaba
  • https://spring.io/projects/spring-data-elasticsearch

你可能感兴趣的:(Java补完系列)