目录

数据库连接池耗尽异常

数据库连接池耗尽异常

文章目录

数据库连接池耗尽异常

1. 出现问题

  • 由于机房问题需要业务服务与数据库全部重启,重启后发现所有测试用户均无法正常访问
重启过程
  • 先重启了 Java 端、C++ 端与大数据端数据库
  • 成功后,Java 端重启各种支撑类微服务,C++ 端重启底层微服务
  • 双方均成功后,Java 端重启上层的调用服务、定时服务、与 C++ 连接服务等
  • 均成功后,开放测试用户对功能进行测试,发现全量用户均无法正常登录访问

2. 分析过程

1. 数据库的连接池打满
  • 通过异常报警监控发现,对接 C++ 的微服务,大量抛出异常、整理发现调用大量微服务超时,异常为: Caused by: com.alibaba.dubbo.remoting.TimeoutException
  • C++ 端也反应,对接的微服务没有注册到 consul 注册中心上,连接不上 C++,由于登录需要查询 C++ 底层的信息,因此无法登录
  • 选择任意微服务查看日志,发现输出异常是: Caused by: org.apache.tomcat.jdbc.pool.PoolExhaustedException ,看来是数据库连接池打满了
2. 紧急处理尝试重启
  • 思考可能是由于业务重启后太多查询的调用,某些缓存可能又没设置好(缓存穿透或缓存雪崩之类),导致大量请求数据库连接,导致连接池打满

  • 因此先关闭不重要的定时任务等,减少测试用户,重启服务进程、让连接池重新生成,一会儿又被打满

  • 问题分析

    *首先排除了查询暴增的问题

    • 又因为连接池很快就打满了、因此不可能是连接池泄露
    • 也未改动过代码,数据库启动页是正常的
    • 因此只可能是连接数据库失败了
  • 现在问题就是找到连接失败的数据库,查下配置啥的

3. 确认问题,找到异常数据库
  • 我们微服务使用的是 Dubbo,因此找个抛数据库连接池耗尽的 Dubbo,控制打印出 Dubbo_JStack.log 日志

  • 在 Linux 目录中找:/home/admin/Dubbo_JStack.log.2021-12-16_08/41/03,这个是 Dubbo 线程的堆栈信息

  • 通过查询日志有大量等待锁的线程:

    "hystrix-com.xxx.service.XxxService-10" Id=2042 WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@5a47b2ae

    "hystrix-com.xxx.service.XxxService-20" Id=799 BLOCKED on org.apache.commons.dbcp.PoolableConnectionFactory@57d6bdd8 owned by "hystrix-com.xxx.service.XxxService-5" Id=707

  • 此时问题知道了:大量线程通过 dbcp 线程池连接数据库不成功,印证了之前的猜测

  • 通过打印的代码 com.xxx.service.XxxService 找到对应库,发现数据库配置和代码配置不一样了,可能重启时被改掉了

3. 解决方案

  • 修改数据库中的配置和代码一致,重启服务进程就解决了