平时工作用数据库连接池的时候,有时候会遇见超时获取不到的报错:

Connection is not available, request timed out after XXms.

但是,并不能一下子看出什么问题导致,因为可能性有蛮多:

1. 可能是真的连接池负载高了

这种情况,连接数达到最大连接数,并且所有连接都处于 active 状态, 一般有2个原因

1.1 流量突增

初步判断:qps 突增,大大超过原预估的连接池容量需求

进一步判断:

  • 前端业务做活动(比如营销活动)没有告知后端/平台服务?
  • soa 流量倾斜到某个机器?
  • ...

1.2 处理变慢

处理变慢,连接归还连接池就慢,单位时间一个连接处理的请求数就降低
初步判断:sql耗时曲线增高

进一步判断: 这种情况会负载些 要综合看各项指标

  • 可能是 机器fullgc了
  • cpu、io抖动了
  • 存在慢sql
  • db抖动
  • 数据库事务死锁
  • 。。。

2. 连接建立失败

当然,有可能你发现连接池还没达到最大连接数,但是就是超时获取不到; 这时候很大的概率是db 连不上了,或者 机器和db之间的网络存在问题

这种比较好判断:可以进一步从报错堆栈中检查,是 socket timeout 还是其他什么具体原因

总结

同一个报错,可能有各种各样的原因,不要急于归结于一个点,要综合、客观地分析各种现象;
同时,建立完善的监控、埋点,以便快速收集客观、全面、时间递进的数据帮助排障; 比如第一类原因, 没有监控图标、没有曲线图,就需要你具备老道的经验,还得一个个的去检查,才能最后定位根因