mysql断线重连报错The last packet successfully received from the server was xxxxxx milliseconds ago

mysql断线重连报错

The last packetsent successfully to the server was 56,506,871 milliseconds ago.
islonger than the server configuredvalue of 'wait_timeout'. You shouldconsider
either expiring and/ortesting connection validity beforeuse in your application, 
increasingthe server configured valuesfor client timeouts, or using 
theConnector/J connection property'autoReconnect=true' to avoid thisproblem.

首先我说下我的开发环境,springboot2.1.4, 我这里是需要多个数据源,用的是阿里的Druid连接池,出现这个报错的都是从库,主库目前还没出现这种情况,我的mysql是5.7的,数据库默认的wait_timeout是28800,8小时,好,下面贴下我的从库的配置(单数据源的就比较简单了,此配置就可以搞定了):

 deputy:  #从数据源
        enabled: true
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/xxxxxxxx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
        # 初始连接数
        initialSize: 10
        # 最大连接池数量
        maxActive: 100
        # 最小连接池数量
        minIdle: 10
        # 配置获取连接等待超时的时间
        maxWait: 60000
        poolPreparedStatements: true
        maxPoolPreparedStatementPerConnectionSize: 20

        # 配置一个连接在池中最大生存的时间,单位是毫秒 900000
        maxEvictableIdleTimeMillis: 200000
        # 配置一个连接在池中最小生存的时间,单位是毫秒 100000
        minEvictableIdleTimeMillis: 100000

        validationQuery: SELECT 1
        # 10000
        validationQueryTimeout: 10000
		#建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于
        #timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
        testWhileIdle: true
        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒   60000
        timeBetweenEvictionRunsMillis: 60000
        #指明是否在从池中取出连接前进行检验,如果检验失败,
        #则从池中去除连接并尝试取出另一个.
        testOnBorrow: false
        testOnReturn: false
        filters: stat,log4j2

        # 是否在自动回收超时连接的时候打印连接的超时错误
        #logAbandoned: true
        # 是否自动回收超时连接
        #removeAbandoned: true
        # 超时时间(以秒数为单位) 这里1800就是30分钟,这个时间要小于数据库的wait_timeout
        #数据库的wait_timeout单位是秒,默认是8小时,超过8小时数据库就自动断开连接
        #removeAbandonedTimeout: 1800

数据库默认wait_timeout是8小时,超过8小时就自动断开连接,一觉醒来 来上班,就报这个鬼玩意,重启项目是没问题的,我总不能每天都重启吧

下面来分析几种方法
方法1:
url后面加 autoReconnect=true ,我试过了,我的mysql5.7 没卵用,

方法2:
加 testWhileIdle: true timeBetweenEvictionRunsMillis: 60000,等等都没用,我干

方法3:
加 removeAbandoned: true removeAbandonedTimeout: 1800 ,它不报The last packetsent successfully to the server was 56,506,871 milliseconds ago 这种错了,报database colse这种错, 还是不行,

方法4:
修改 mysql的wait_timeout,最大24天左右, 不是不行,是不敢,服务器上N多项目,到时候扎堆的空闲连接,无法回收,那还不炸了,不靠谱
写到这,我已经心灰意冷了,

方法5:
我用了个最沙雕的方法,做个定时任务去查询我的从数据源,随便写个select ,每5小时,或者6小时执行一次,反正不超过8小时就行,保证mysql一直能连接,
求解脱。。。。。。

方法6: 最终方案
yml文件中添加两个属性
keepAlive: true
phyTimeoutMillis: 25200000

 deputy:  #从数据源
        enabled: true
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/xxxxxxxx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
        # 初始连接数
        initialSize: 10
        # 最大连接池数量
        maxActive: 100
        # 最小连接池数量
        minIdle: 10
        # 配置获取连接等待超时的时间
        maxWait: 60000
        poolPreparedStatements: true
        maxPoolPreparedStatementPerConnectionSize: 20

        # 配置一个连接在池中最大生存的时间,单位是毫秒 900000
        maxEvictableIdleTimeMillis: 200000
        # 配置一个连接在池中最小生存的时间,单位是毫秒 100000
        minEvictableIdleTimeMillis: 100000

        validationQuery: SELECT 1
        # 10000
        validationQueryTimeout: 10000
		#建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于
        #timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
        testWhileIdle: true
        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒   60000
        timeBetweenEvictionRunsMillis: 60000
        #指明是否在从池中取出连接前进行检验,如果检验失败,
        #则从池中去除连接并尝试取出另一个.
        testOnBorrow: false
        testOnReturn: false
        filters: stat,log4j2
        # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作
        keepAlive: true
        # 允许物理连接最大存活时间,单位是毫秒
        phyTimeoutMillis: 25200000

在添加数据源的代码中配置它的一些属性:

 public DataSource deputyDataSource(Environment env)
    {
        Properties prop = build(env, "spring.datasource.druid.deputy.");
        AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
        xaDataSource.setXaDataSourceClassName(xaDataSourceClassName);
        xaDataSource.setUniqueResourceName(DataSourceType.DEPUTY.name());
        xaDataSource.setXaProperties(prop);
        xaDataSource.setMaxIdleTime(25200);
        xaDataSource.setMaxLifetime(25200);
        xaDataSource.setTestQuery("SELECT 1 ");
        xaDataSource.setMaxPoolSize(100);
        xaDataSource.setMinPoolSize(5);
        return xaDataSource;
    }

我这里是通过这个build方法,获取yml的配置属性的,这里put的属性,在yml文件中一定要有,不然报空指针,主从库都要添加,具体看所使用的框架

    private Properties build(Environment env, String prefix) {
        Properties prop = new Properties();
        prop.put("url", env.getProperty(prefix + "url"));
        prop.put("username", env.getProperty(prefix + "username"));
        prop.put("password", env.getProperty(prefix + "password"));
        prop.put("driverClassName", env.getProperty(prefix + "driverClassName", ""));
        prop.put("initialSize", env.getProperty(prefix + "initialSize", Integer.class));
        prop.put("maxActive", env.getProperty(prefix + "maxActive", Integer.class));
        prop.put("minIdle", env.getProperty(prefix + "minIdle", Integer.class));
        prop.put("maxWait", env.getProperty(prefix + "maxWait", Integer.class));
        //prop.put("maxEvictableIdleTimeMillis", env.getProperty(prefix + "maxEvictableIdleTimeMillis", Integer.class));
        prop.put("poolPreparedStatements", env.getProperty(prefix + "poolPreparedStatements", Boolean.class));
        prop.put("maxPoolPreparedStatementPerConnectionSize",
                env.getProperty(prefix + "maxPoolPreparedStatementPerConnectionSize", Integer.class));
        prop.put("maxPoolPreparedStatementPerConnectionSize",
                env.getProperty(prefix + "maxPoolPreparedStatementPerConnectionSize", Integer.class));
        prop.put("validationQuery", env.getProperty(prefix + "validationQuery"));
        prop.put("validationQueryTimeout", env.getProperty(prefix + "validationQueryTimeout", Integer.class));
        prop.put("testOnBorrow", env.getProperty(prefix + "testOnBorrow", Boolean.class));
        prop.put("testOnReturn", env.getProperty(prefix + "testOnReturn", Boolean.class));
        prop.put("testWhileIdle", env.getProperty(prefix + "testWhileIdle", Boolean.class));
        prop.put("timeBetweenEvictionRunsMillis",
                env.getProperty(prefix + "timeBetweenEvictionRunsMillis", Integer.class));
        prop.put("minEvictableIdleTimeMillis", env.getProperty(prefix + "minEvictableIdleTimeMillis", Integer.class));
        prop.put("filters", env.getProperty(prefix + "filters"));
        prop.put("keepAlive", env.getProperty(prefix + "keepAlive", Boolean.class));
        prop.put("phyTimeoutMillis", env.getProperty(prefix + "phyTimeoutMillis", Integer.class));
        return prop;
    }

ok 收工!

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
MySQL报错"The last packet successfully received from the server was X milliseconds ago"时,这通常是由于连接超时引起的。解决这个问题的方法有以下几种: 1. 检查网络连接:首先确保网络连接正常,可以尝试使用其他网络连接或者重启网络设备。 2. 调整连接超时时间:可以通过修改MySQL配置文件中的"wait_timeout"参数来增加连接超时时间。该参数表示MySQL服务器在没有活动连接的情况下等待的时间,默认为8小时。可以将其增加到更大的值,例如设置为28800(8小时)。 3. 优化查询性能:如果查询语句执行时间过长,可能会导致连接超时。可以通过优化查询语句、创建索引、调整数据库结构等方式来提高查询性能,减少连接超时的可能性。 4. 增加服务器资源:如果服务器资源不足,可能会导致连接超时。可以考虑增加服务器的内存、CPU等资源,以提高服务器的处理能力。 5. 使用长连接:长连接是指在一个连接上可以执行多个查询,而不是每次查询都建立一个新的连接。使用长连接可以减少连接建立和断开的开销,降低连接超时的可能性。 6. 检查防火墙设置:有时防火墙设置可能会导致连接超时。确保防火墙没有阻止MySQL服务器的访问。 希望以上方法能够帮助您解决MySQL报错"The last packet successfully received from the server was X milliseconds ago"的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值