Thread starvation or clock leap detected (housekeeper delta=4m32s295ms949µs223ns).

问题:
2020-03-18 09:44:03.404 WARN 10900 --- [datasource housekeeper] com.zaxxer.hikari.pool.HikariPool : datasource - Thread starvation or clock leap detected (housekeeper delta=10m28s381ms837µs874ns).

分析:
WARN, 警告级别,看起来不是什么错误,但是连接数据库就是连不上

英译汉:数据源-检测到线程饥饿或时钟跳动
人话:要么是检测到等待连接的时间过长,造成进饥饿;要么是检测到时钟跳动,反正最后是关闭了数据库连接。

看了看我的数据库连接池配置,并没有使用hikari, 应该是springboot默认的方式

datasource:
    name: datasource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://${ip}:3306/${数据库}?useSSL=false&characterEncoding=UTF-8
    username: ${username}
    password: ${password}

这里说一下hikari连接池吧:
hikari, 号称最快连接池,光速嘛,springboot 2.x 默认数据库连接池。
这个确实是默认的,不需要再引入依赖
顺便找找源码中有没有日志的警告:

public void run()
      {
         try {
            // refresh values in case they changed via MBean
            connectionTimeout = config.getConnectionTimeout();
            validationTimeout = config.getValidationTimeout();
            leakTaskFactory.updateLeakDetectionThreshold(config.getLeakDetectionThreshold());
            catalog = (config.getCatalog() != null && !config.getCatalog().equals(catalog)) ? config.getCatalog() : catalog;

            final long idleTimeout = config.getIdleTimeout();
            final long now = currentTime();

            // Detect retrograde time, allowing +128ms as per NTP spec.
            if (plusMillis(now, 128) < plusMillis(previous, HOUSEKEEPING_PERIOD_MS)) {
               LOGGER.warn("{} - Retrograde clock change detected (housekeeper delta={}), soft-evicting connections from pool.",
                           poolName, elapsedDisplayString(previous, now));
               previous = now;
               softEvictConnections();
               return;
            }
            else if (now > plusMillis(previous, (3 * HOUSEKEEPING_PERIOD_MS) / 2)) {
               // No point evicting for forward clock motion, this merely accelerates connection retirement anyway
               //.....没错,就是它 在这里..................
               LOGGER.warn("{} - Thread starvation or clock leap detected (housekeeper delta={}).", poolName, elapsedDisplayString(previous, now));
            }

            previous = now;

            String afterPrefix = "Pool ";
            if (idleTimeout > 0L && config.getMinimumIdle() < config.getMaximumPoolSize()) {
               logPoolState("Before cleanup ");
               afterPrefix = "After cleanup  ";

               final List<PoolEntry> notInUse = connectionBag.values(STATE_NOT_IN_USE);
               int toRemove = notInUse.size() - config.getMinimumIdle();
               for (PoolEntry entry : notInUse) {
                  if (toRemove > 0 && elapsedMillis(entry.lastAccessed, now) > idleTimeout && connectionBag.reserve(entry)) {
                     closeConnection(entry, "(connection has passed idleTimeout)");
                     toRemove--;
                  }
               }
            }

            logPoolState(afterPrefix);

            fillPool(); // Try to maintain minimum connections
         }
         catch (Exception e) {
            LOGGER.error("Unexpected exception in housekeeping task", e);
         }
      }

now > plusMillis(previous, (3 * HOUSEKEEPING_PERIOD_MS) / 2)

No point evicting for forward clock motion, this merely accelerates connection retirement anyway
英译汉: 没有任何必要将时钟向前移动,这只会加速连接的退出

来看看连接被移除的几种情况:
HouseKeeper是一项30s周期的检测任务,

  1. 时钟倒退,驱逐连接; (此处需要结合案列)
  2. 驱逐超出idle-timeout时间的空闲连接,

解决:
使用自定义hikari配置,
并设置以下参数

datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://${ip}:3306/${数据库}?useSSL=false&characterEncoding=UTF-8
    username: ${username}
    password: ${password}
    hikari:
      auto-commit: true
      #空闲连接超时时长
      idle-timeout: 60000
      #连接超时时长
      connection-timeout: 60000
      #最大生命周期,0不过期
      max-lifetime: 0
      #最小空闲连接数
      minimum-idle: 10
      #最大连接数量
      maximum-pool-size: 10
  • 19
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值