springboot The last packet succe

作者: 黑猫警长1122 | 来源:发表于2019-06-24 11:19 被阅读0次

    场景:
    springboot项目,一段时间就报错,The last packet successfully received from the server was...,提示连接失效。修改过数据源配置、有效性检查、数据库配置,依旧出现问题。

    原因:
    查看springboot启动日志,发现提示:testWhileIdle is true, validationQuery not set
    说明连接有效性检查是开启的,但是检查所需要的语句没有设置。
    但是在springboot配置文件中是有设置的:

    ##########################  druid配置   ##########################
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    
    # 初始化大小,最小,最大
    spring.datasource.initialSize=5
    spring.datasource.minIdle=5
    spring.datasource.maxActive=20
    # 配置获取连接等待超时的时间
    spring.datasource.maxWait=60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    spring.datasource.timeBetweenEvictionRunsMillis=60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    spring.datasource.minEvictableIdleTimeMillis=300000
    # 校验SQL,Oracle配置 spring.datasource.validationQuery=SELECT 1 FROM DUAL,如果不配validationQuery项,则下面三项配置无用
    spring.datasource.validationQuery=SELECT 'x'
    spring.datasource.testWhileIdle=true
    spring.datasource.testOnBorrow=false
    spring.datasource.testOnReturn=false
    # 打开PSCache,并且指定每个连接上PSCache的大小
    spring.datasource.poolPreparedStatements=true
    spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    spring.datasource.filters=stat,wall,log4j
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    # 合并多个DruidDataSource的监控数据
    spring.datasource.useGlobalDataSourceStat=true
    

    也就是说,springboot启动注入出现问题了。

    解决方式:

    1. 首先判断是否配置问题,之前开发过很多springboot的项目,没有遇到过类似的问题,分析和旧项目的区别:引入druid
    2. 分析是否druid的问题,查阅资料后没有得到结果,从google分享配置上看没有问题
    3. 分析是否springboot注入问题,查阅资料后发现,springboot1.4后取消了spring.datasource.type注入,得到答案,注入要自己写配置类
    4. 实现配置类
    @Configuration
    
    public class DruidConfiguration {
    
        @Value("${spring.datasource.url}")
    
        private String dbUrl;
    
        @Value("${spring.datasource.username}")
    
        private String username;
    
        @Value("${spring.datasource.password}")
    
        private String password;
    
        @Value("${spring.datasource.driver-class-name}")
    
        private String driverClassName;
    
        @Value("${spring.datasource.initialSize}")
    
        private int initialSize;
    
        @Value("${spring.datasource.minIdle}")
    
        private int minIdle;
    
        @Value("${spring.datasource.maxActive}")
    
        private int maxActive;
    
        @Value("${spring.datasource.maxWait}")
    
        private int maxWait;
    
        @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    
        private int timeBetweenEvictionRunsMillis;
    
        @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    
        private int minEvictableIdleTimeMillis;
    
        @Value("${spring.datasource.validationQuery}")
    
        private String validationQuery;
    
        @Value("${spring.datasource.testWhileIdle}")
    
        private boolean testWhileIdle;
    
        @Value("${spring.datasource.testOnBorrow}")
    
        private boolean testOnBorrow;
    
        @Value("${spring.datasource.testOnReturn}")
    
        private boolean testOnReturn;
    
        @Value("${spring.datasource.poolPreparedStatements}")
    
        private boolean poolPreparedStatements;
    
        @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    
        private int maxPoolPreparedStatementPerConnectionSize;
    
        @Value("${spring.datasource.filters}")
    
        private String filters;
    
        @Value("${spring.datasource.connectionProperties}")
    
        private String connectionProperties;
    
        @Value("${spring.datasource.useGlobalDataSourceStat}")
    
        private boolean useGlobalDataSourceStat;
    
    
    
        @Bean     //声明其为Bean实例
    
        @Primary  //在同样的DataSource中,首先使用被标注的DataSource
    
        public DataSource dataSource(){
    
            DruidDataSource datasource = new DruidDataSource();
    
            datasource.setUrl(this.dbUrl);
    
            datasource.setUsername(username);
    
            datasource.setPassword(password);
    
            datasource.setDriverClassName(driverClassName);
    
    
    
            //configuration
    
            datasource.setInitialSize(initialSize);
    
            datasource.setMinIdle(minIdle);
    
            datasource.setMaxActive(maxActive);
    
            datasource.setMaxWait(maxWait);
    
            datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
    
            datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    
            datasource.setValidationQuery(validationQuery);
    
            datasource.setTestWhileIdle(testWhileIdle);
    
            datasource.setTestOnBorrow(testOnBorrow);
    
            datasource.setTestOnReturn(testOnReturn);
    
            datasource.setPoolPreparedStatements(poolPreparedStatements);
    
            datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
    
            datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
    
            try {
    
                datasource.setFilters(filters);
    
            } catch (SQLException e) {
    
                System.err.println("druid configuration initialization filter: "+ e);
    
            }
    
            datasource.setConnectionProperties(connectionProperties);
    
            return datasource;
    
        }
    
    }
    

    再次启动正常,运行一段时间后无超时现象,说明连接有效性检查生效

    相关文章

      网友评论

        本文标题:springboot The last packet succe

        本文链接:https://www.haomeiwen.com/subject/lfsnqctx.html