flink任务ERROR com.alibaba.druid.pool.DruidDataSource discard

flink任务ERROR com.alibaba.druid.pool.DruidDataSource discard

首页战争策略演义三国叁更新时间:2024-06-03
报错的关键信息如下

2023-07-24 21:54:41,754 ERROR com.alibaba.druid.pool.DruidPooledStatement [] - CommunicationsException, druid version 1.2.8, testWhileIdle true, idle millis 30042, minIdle 5, poolingCount 4, timeBetweenEvictionRunsMillis 60000, lastValidIdleMillis 30042, driver com.mysql.cj.jdbc.Driver, exceptionSorter com.alibaba.druid.pool.vendor.MySqlExceptionSorter 2023-07-24 21:54:41,755 ERROR com.alibaba.druid.pool.DruidDataSource [] - {conn-16455} discard com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure


百度了很多,都说什么配置之类的,但是我是运行一段时间以后才会出问题的;

原因

1、我设置的连接池最小的连接数是5,可用的是4个,有一个是被弃用的

2、连接池会一直保持最小连接数,认为里面都是可用的

3、从连接池中获取连接,取到的是哪个被弃用的,所以报错

我要的目的

是让程序出问题的时候,能够继续运行下去,我从不要求程序运行一直不出问题,我要的是出了以问题以后能够继续运行!!!!


解决思路

1、在从druid数据库连接池获取Connection的时候,try catch,若抛异常属于discard这种的,我就关闭连接池,重开连接池;

public Connection getConnection(JSONObject obj) { Connection conn = null; try { conn = Sink.dataSource.getConnection(); } catch (Exception e) { logger.error("druid连接池发生discard异常" e.getMessage()); Sink.dataSource.close(); Sink.dataSource = new Driud().getSource(); logger.error("dataSource 重新创建了"); } return null; } return conn; }

2、增大连接池最小连接池数,降低这种风险(从最小连接池里面取可用连接)

dataSource.setInitialSize(15); dataSource.setMinIdle(15); //最小连接池数量

3、归还的时候,借出的时候都校验一下

dataSource.setTestWhileIdle(true); // <!-- 这里建议配置为TRUE,防止取到的连接不可用 --> dataSource.setTestOnBorrow(true); dataSource.setTestOnReturn(true);

比起性能,我觉得稳定性更重要

4、之前代码为了方便,增删改查都用一个链接Connection connection; 这样在并发情况下会泄露资源;代码不够健壮;

每个对数据库的操作都使用一个链接,操作数据库结束以后一个个个关闭

贴上我完整的连接池配置代码

package Jdbc; import com.alibaba.druid.pool.DruidDataSource; public class Driud { private static DruidDataSource dataSource = null; public DruidDataSource getSource(){ dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://11.11.2.190:3306/jx_cloud_mes?serverTimezone=Asia/Shanghai&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useLegacyDatetimeCode=false"); dataSource.setUsername("root"); dataSource.setPassword("ems_2022"); dataSource.setInitialSize(15); dataSource.setMinIdle(15); //最小连接池数量 dataSource.setMaxActive(30); //最大连接池数量 dataSource.setMaxWait(60000); //获取连接时最大等待时间,单位毫秒。配置了maxWait之后, dataSource.setValidationQuery("select 1"); dataSource.setTestWhileIdle(true); // <!-- 这里建议配置为TRUE,防止取到的连接不可用 --> dataSource.setTestOnBorrow(true); dataSource.setTestOnReturn(true); dataSource.setTimeBetweenEvictionRunsMillis(60000); //有两个含义:1) Destroy线程会检测连接的间隔时间2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明 dataSource.setMinEvictableIdleTimeMillis(25200000); //<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> dataSource.setPoolPreparedStatements(true); dataSource.setMaxPoolPreparedStatementPerConnectionSize(20); dataSource.setKeepAlive(true); dataSource.setLogAbandoned(true); dataSource.setRemoveAbandoned(true); dataSource.setRemoveAbandonedTimeout(1800); return dataSource; } }


突然发现try catch非常重要,一个程序运行几天可能没问题,但是运行很久,需要考虑各个方面。

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved