秒杀开始3秒,数据库连接池就被打满了,100万用户在页面上干等
去年我们搞了一次周年庆秒杀。活动页面提前一周预热,到点那一刻,后台监控直接变成一片红。 不是 QPS 被打爆——网关和应用层都扛住了。是数据库连接池,三秒之内从 0 飙到 200(最大连接数),然后所有请求开始报 Cannot get JDBC Connection。 最离谱的是,库存表一行没动。 因为所有请求刚到数据库门口,就被连接池耗尽的异常挡回去了。秒杀还没开始,数据库先倒下了。 一、连接池为什么瞬间被榨干 常规架构下,每次请求处理到数据库这一步才会获取连接。秒杀场景的流量是瞬时脉冲——0 秒之前无人问津,0 秒之后几十万并发同时冲到数据库门口。 连接池有个坑:它不会拒绝你,它只会让你排队等。 HikariCP 默认最大连接数 10(或者你手动设的 200),当并发的数据库请求数超过这个值时,获取连接的线程进入等待队列。每个请求最多等 connectionTimeout(默认 30 秒)。秒杀场景下 30 秒太长了—— 所有线程都在等连接 连接被前面进来的请求占用着(那些请求可能正在执行慢查询) 后面的请求继续涌进来抢连接 线程池里的线程全卡在获取连接上,CPU 空转 tom....