【bug】内存占用过高,当前为[61G]

功能回顾

在这里插入图片描述

当时编写的一个datax-plugin插件,进行定时去采集所有数据库(N个库)下面每一张表(n多表)里面到底有多少数据量(记录数),表更新记录数;有问题关闭不使用了,前几天被小伙伴开起来了,数据量上来了就出现各种问题。内存占用过高、数据库连接不上、依赖版本冲突…

告警消息

这两天遇到一个问题,内存高烧不退

[容器宕机][http://xxx] 无法连接,状态码[0]
[容器宕机][http://xxx] 无法连接,状态码[0]
[容器宕机][http://xxx] 无法连接,状态码[0]
[容器宕机][http://xxx] 无法连接,状态码[0]
[内存占用][IP/DOCKER-NAME] 内存占用过高,当前为[61G]

在这里插入图片描述

原因排查

  1. 发现任务调度被人开启了,自动调度的是每10分钟执行一次
  2. 日志打印内容里大量数据库无法连接
  3. 依赖包版本不一致,执行出现找不到类
  4. 查询获取值时候出现类型错误
  5. 大批量数据逻辑处理
    … … 等问题

解决调整

  • 调度自动时间改成每天一次,改成每天凌晨某时间采集一次;
  • 依赖包版本调整一致 <commons-lang3-version>3.9</commons-lang3-version>
  • 大批量数据调整为分批处理List<List<T>> gDataList = Lists.partition(dataList, 500);
  • 大批量创建Dao查询优化
Map<Integer, MybatisSqlDao> cacheDao = new HashMap<>();
//切割数据集合
List<List<T>> gDataList = Lists.partition(dataList, 500);
for (List<T> dsList: gDataList) {
    for (T item : dsList) {
      MybatisSqlDao localDcSqlDao = cacheDao.get(item.getDid());
      if (localDcSqlDao == null) {
           localDcSqlDao = MybatisSqlDaoFactory.cDao(url, username, password, driverClass);
           cacheDao.put(item.getDid(), localDcSqlDao);
      }
      //TODO 其他业务查询
    }
}
  • 获取空值转换异常
Object num= tableNum.get("NUM");
Long tableNum = Long.valueOf(String.valueOf(num));

调整

Object num = tableNum.get("NUM");
num= ObjectUtil.isNull(num) ? 0L : num; //补充判断
Long tableNum = Long.valueOf(String.valueOf(num));
  • 数据库连接是否正常方式调整
    原先写法(没有任何效果,一致卡在这里):
Connection conn = null;
try {
    Class.forName(driverClass);
    DriverManager.setLoginTimeout(15); //15秒超时
    conn = DriverManager.getConnection(getJdbcUrl(url, driverClass), userName, passWord);
    return true;
} catch (Exception e) {
    e.printStackTrace();
} finally {
    JdbcUtils.close(conn);
}

改造调整(部分参考代码,提供思路)

 /**
 * 判断jdbc连接是否可用
 *
 * @param url
 * @param userName
 * @param passWord
 * @param driverClass
 * @param timeOut     超时时间 单位秒
 * @return
 */
public static boolean isCanConn(String url, String userName, String passWord, String driverClass, int timeOut) {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    String finalUrl = url;
    Future<Connection> future = executor.submit(() -> DriverManager.getConnection(finalUrl, userName, passWord));
    Connection conn = null;
    //TRUE 连接成功,FALSE 连接失败
    boolean status = false;
    try {
        Class.forName(driverClass);
        DriverManager.setLoginTimeout(timeOut); //15秒超时
        if (!getDriverClassName(url).equalsIgnoreCase(driverClass)) {
            throw new RuntimeException("数据库类型与JDBC链接串类型不匹配!");
        }
        conn = future.get(timeOut, TimeUnit.SECONDS);
        status = true;
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    } finally {
        executor.shutdownNow();
        JdbcUtils.closeConnection(conn);
    }
    return status;
}

执行结果

在这里插入图片描述

附加

DataX插件开发宝典

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

掘金者说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值