• 【原创】SpringBoot 2.7.0通过lettuce及commonspool2 v2.9.0集成Redis踩坑记录


    背景

    公司的一个项目由于HTTPS证书到期,导致小程序、POS不能正常使用。所以百度了下,通过URL检测证书有效期的代码,并自行整合到一个服务中。
    代码仓库:[基于SpringBoot + 企业微信 + 钉钉 的通知服务] (https://gitee.com/tec-cloud/tec-notice),由于码云的仓库策略调整,可能无法正常访问。

    问题溯源

    spring: 
      redis:
        client-type: lettuce
        host: 127.0.0.1
        lettuce:
          pool:
            #最大连接数
            max-active: 10
            #连接池中最小空闲连接
            min-idle: 2
            #连接池中最大空闲连接
            max-idle: 3
            #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
            max-wait: 60s
            #空闲链接检测线程检测周期毫秒(负值表示不检测)(类型为Duration,添加秒)
            time-between-eviction-runs: 60s
          #关闭超时时间
          shutdown-timeout: 1s
        port: 6379
        password:
        #连接超时时间毫秒(类型为Duration,添加秒)
        timeout: 60s
    

    以上是redis的配置,想将配置存储在redis中,所以通过lettuce集成spring-boot-starter-data-redis。

    根据依赖传递spring-boot-starter-data-redis v2.7.0 --> lettuce-core v6.1.8.RELEASE --> commons-pool2 v2.9.0定位到依赖配置,如下:

        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-pool2</artifactId>
          <version>2.9.0</version>
          <scope>compile</scope>
          <optional>true</optional>
        </dependency>
    

    同时,我注意到optional=true,所以在项目根pom.xml添加本依赖,并移除optional。如下:

        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-pool2</artifactId>
          <version>2.9.0</version>
          <scope>compile</scope>
        </dependency>
    

    启动后,报错:

    2022-06-12 16:32:17.716 ERROR 15092 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 
    
    ***************************
    APPLICATION FAILED TO START
    ***************************
    
    Description:
    
    An attempt was made to call a method that does not exist. The attempt was made from the following location:
    
        org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$PoolBuilderFactory.getPoolConfig(LettuceConnectionConfiguration.java:185)
    
    The following method did not exist:
    
        org.apache.commons.pool2.impl.GenericObjectPoolConfig.setTimeBetweenEvictionRuns(Ljava/time/Duration;)V
    
    The calling method's class, org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$PoolBuilderFactory, was loaded from the following location:
    
        jar:file:/C:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.7.0/spring-boot-autoconfigure-2.7.0.jar!/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration$PoolBuilderFactory.class
    
    The called method's class, org.apache.commons.pool2.impl.GenericObjectPoolConfig, is available from the following locations:
    
        jar:file:/C:/Users/Administrator/.m2/repository/org/apache/commons/commons-pool2/2.9.0/commons-pool2-2.9.0.jar!/org/apache/commons/pool2/impl/GenericObjectPoolConfig.class
    
    The called method's class hierarchy was loaded from the following locations:
    
        org.apache.commons.pool2.impl.GenericObjectPoolConfig: file:/C:/Users/Administrator/.m2/repository/org/apache/commons/commons-pool2/2.9.0/commons-pool2-2.9.0.jar
        org.apache.commons.pool2.impl.BaseObjectPoolConfig: file:/C:/Users/Administrator/.m2/repository/org/apache/commons/commons-pool2/2.9.0/commons-pool2-2.9.0.jar
        org.apache.commons.pool2.BaseObject: file:/C:/Users/Administrator/.m2/repository/org/apache/commons/commons-pool2/2.9.0/commons-pool2-2.9.0.jar
    
    
    Action:
    
    Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.boot.autoconfigure.data.redis.LettuceConnectionConfiguration$PoolBuilderFactory and org.apache.commons.pool2.impl.GenericObjectPoolConfig
    
    Disconnected from the target VM, address: '127.0.0.1:51044', transport: 'socket'
    
    Process finished with exit code 1
    
    

    根据日志,确认错误:不存在GenericObjectPoolConfig.setTimeBetweenEvictionRuns方法,启动发生错误,终止并退出。

    本着周末不学习就是退步的想法,跟踪了https://github.com/apache/commons-pool.githttps://github.com/spring-projects/spring-boot.git对应的版本、TAG及commit history。仅在spring-boot的提交记录中发现一点端倪。
    如图:


    不过提交时间是在spring-boot v2.7.x的初始化发布日期2022-05-19之前,参考:https://spring.io/projects/spring-boot#support

    最终只要带着这个困惑,翻阅spring-boot、spring-data-redis的closed的Issue,结果被我搜个正着。
    https://github.com/spring-projects/spring-data-redis/issues?q=is%3Aissue+is%3Aclosed+GenericObjectPoolConfig
    根据其中的讨论,得到有效信息,依赖版本有冲突,删掉了2.9.0:The problem solved by deleting explicit dependency org.apache.commons:commons-pool2:2.9.0. Now it uses commpons-pool2:2.11.1
    见链接:
    https://github.com/spring-projects/spring-data-redis/issues/2293#issuecomment-1084310766

    马不停蹄地开始试验:

            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
    

    服务正常启动了。

    解决方案

    版本由spring-boot-dependencies来控制,直接读取<commons-pool2.version>2.11.1</commons-pool2.version>即可。当然也可以使用${commons-pool2.version}来明确定义版本。

            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
    
  • 相关阅读:
    js常用设计模式实现(一)单例模式
    js深入(四)万脸懵圈的this指向
    js深入(三)作用域链与闭包
    js深入(二)函数的执行与上下文
    js深入(一)从原型理解原型链
    初识markdown
    git stash 用法
    见的如T、E、K、V等形式的参数常用于表示泛型形参
    SystemBarTint是两年以前的一个开源库,现在我们依然可以用它很方便的给应用加上。
    android:supportsRtl="true" 属性
  • 原文地址:https://www.cnblogs.com/Candies/p/16368312.html
Copyright © 2020-2023  润新知