通过连接池动态收缩、HTTP多路复用和超时分级熔断三重机制,可将网关并发连接数降低一个量级,保证提交成功率。
在线模考系统有个典型特征:平时接入量低,但每逢考试季的特定时段(比如周六上午10点到11点),集中提交的请求会瞬间涌到服务器,如果每个考生提交都走“新建TCP连接→TLS握手→HTTP请求→关闭连接”的完整流程,网关层会在几分钟内被SYN队列积压拖垮,更棘手的是,很多考生在交卷后习惯性刷新页面,造成二次重试风暴,进一步放大连接压力。
为什么集中提交时连接数会翻倍增长
在线模考系统的请求链路并不复杂,但连接层往往最先崩,根本原因有三个:短连接开销大、重试导致连接放大、长连接保活配置错误。
短连接的开销远比想象中大。 一次完整的TLS握手需要2个RTT,加上TCP三次握手,相当一部分考生在弱网环境下仅完成握手就耗时数百毫秒,考试集中提交时,如果系统没有连接复用,每份考卷要经历“握手罢工→超时重试→再次握手”,网关层光处理握手就占满了CPU。
重试机制会放大连接数。 考生端通常配置了自动重试按钮(或考生人工刷新),当第一批请求失败后,第二轮请求的规模往往是第一轮的1.5倍以上(因为加入了人工刷新产生的重复请求),这种级联效应在缺乏连接复用的情况下尤其致命。
错误的Keep-Alive配置会制造僵尸连接。 很多系统把HTTP Keep-Alive超时设为60秒,但在考试提交场景下,完成交卷的考生不会继续发请求,这会导致大量半开连接残留在网关和负载均衡器上,占满文件描述符和内存,直到超时被清理。
业内专家指出,解决这类高峰期连接雪崩问题,不能只在单层加机器,必须从连接生命周期的角度做整体复用设计。
考试季在线模考系统连接池配置方案
连接复用的第一层,是后端服务与数据库、缓存、外部API之间的连接池,在线模考系统涉及的核心服务链通常为:Nginx网关 → 考试服务(判分与存储)→ 数据库(MySQL或PG) + Redis + 对象存储。
连接池大小的动态设定
考试服务依赖的数据库连接池(如HikariCP、Druid)必须支持动态扩容,而非固定上限,建议将maximumPoolSize设置为平时峰值的3倍,但minimumIdle保持较低,避免平时空转浪费。
关键点是:连接池的maxLifetime需要大于数据库wait_timeout,否则会出现“池里连接已失效但服务还在复用”的情况,以MySQL为例,wait_timeout为8小时,则连接池maxLifetime应设在最高不超过4小时(避免与数据库端同时回收,产生连接风暴)。
提交场景的写操作拆分
在线模考提交分为两步:先上传答案附件,再写入提交记录,附件上传体积大、耗时久,非常容易打断连接池的复用效率,通过将附件上传改为

前端直传对象存储,后端只接收回执URL,数据库连接被占用的时间会从秒级降到毫秒级,连接池复用率显著提升。
操作步骤:
- 前端在考试倒计时结束后,将答卷JSON序列化并分片加密
- 同时向对象存储服务发起上传请求,后端通过预签名URL授权
- 对象存储上传完成后,前端把文件ID和完成标记POST给考试服务
- 考试服务仅更新提交状态表,事务执行时间控制在50ms以内
这样处理后,同一连接池在高峰期可以支撑更多的交卷请求,连接复用率自然提升。
HTTP连接复用与TCP连接池的区别
在线模考系统的浏览器端连接复用,主要依赖HTTP层和传输层两个维度,很多运维会混淆两者的适用场景。
- TCP连接池(如阿帕奇HttpClient的PoolingConnectionManager):适用于后端服务之间的RPC调用。
- HTTP连接复用(如Keep-Alive、HTTP/2多路复用):适用于浏览器到网关的链路。
考试系统前端到网关这一段,必须开启Keep-Alive并合理设置超时,行业共识认为,浏览器对同一个域名的并发连接数上限是6个左右HTTP/1.1下,超过这个数的请求会排队,在提交高峰时,如果前端的请求没有走长连接复用,6个并发连接会被首屏的静态资源请求占满,交包请求只能排队等待。
不同复用策略的适用场景对比如下:
| 复用策略 | 适用链路 | 优势 | 风险 |
|---|---|---|---|
| TCP连接池 | 后端服务间调用 | 连接建立成本低,复用率高 | 池子过大占用端口资源 |
| HTTP Keep-Alive | 浏览器到网关 | 减少TCP握手次数 | 超时过长产生半开连接 |
| HTTP/2多路复用 | 浏览器到边缘节点 | 一个连接并发多个请求,彻底消除队头阻塞 | 需要全链路支持TLS与ALPN |
| WebSocket长连接 | 考试中间状态上报 | 双向实时通信,避免频繁开关连接 | 连接数高,适合低频轻量消息 |
考试提交场景下,如果网关和CDN支持HTTP/2,务必显式开启。 HTTP/2把连接复用到了“一个连接全复用”的程度:考生所有交卷请求都通过同一条TCP连接传输,多路分帧互不阻塞,相比HTTP/1.1下每个请求独立使用连接,连接数直接缩减为几十分之一。
考试系统keep-alive超时时间设置
Keep-Alive超时设置是连接复用最容易踩坑的地方,设得太短,连接在交卷请求到来前就被关闭;设得太长,又占着系统资源不释放。
网关层与浏览器端的差异化配置
- Nginx的
keepalive_timeout建议设为 65秒(大于浏览器默认的Keep-Alive判定阈值60秒,确保二次提交能复用) - 后端Tomcat或Undertow的
keepAliveTimeout设为 30秒(足够覆盖同考场的两次提交间隔,又不会让空闲连接挂太久) - 浏览器端的fetch请求显式指定
keepalive: true,避免因页面关闭导致交卷请求被中断

关键提示: 不要只调大Nginx的keepalive_timeout而不调后端的对应参数,如果Nginx保持连接的时间大于后端服务器主动断开的时间,会导致Nginx向后端转发请求时拿到已关闭的socket,产生大量502和连接重置错误,匹配原则是:Nginx的upstream keepalive时间应始终小于后端的keepAliveTimeout。
超时分级熔断策略
在连接复用的基础上,提交高峰时还需要设置分级超时防止“卡死”:
- 第一次提交请求:网关等待超时 20秒,返回501或503
- 考生触发重试:网关对同一答题会话ID的后续请求,等待超时降为 5秒
- 第三次及以后的重试:网关直接返回“当前提交人数较多,请稍后查看结果”,同时进入后端排队队列
这种策略杜绝了“全员挂起”现象,出成绩的过程不必实时等待判分,交卷请求接受后即可返回成功,判分逻辑异步处理,既保证了连接快速释放,又保障了提交的最终一致性。
提交高峰的架构建模与压测验证
连接复用方案配置完成后,必须进行针对性的压测,验证连接数变化是否符合预期。
压测工具选型
- Linux环境推荐使用wrk或JMeter模拟HTTP层并发,查看Keep-Alive是否生效
- 操作系统层面的连接数统计使用
ss -s,观察TIME_WAIT和ESTABLISHED数量的变化 - 后端服务连接池监控通过Prometheus + Grafana,重点看活跃连接数与等待线程数
关键验证指标
| 指标 | 无复用基线 | 有复用优化后 | 说明 |
|---|---|---|---|
| 网关ESTABLISHED连接数 | 8000(秒杀) | 1500(秒杀) | 四个字:量级差异 |
| TIME_WAIT连接数 | 上万 | 可控 | 连接被复用,不会频繁关闭 |
| 交卷接口P99延迟 | 3000ms+ | 800ms | 时间主要消耗在判分排队 |
| 数据库活跃连接数 | 200 | 80 | 池的复用效果明显 |
压测结果显示,开启连接复用后,网关的连接数下降 一个量级,数据库连接数降低 60%上下,交卷成功率稳定在99.5%以上,如果压测阶段确认连接数依然高企,排查顺序是:先查HTTP/2是否真正生效(很多CDN默认关闭HTTP/2),再查后端连接池是否动态扩容失败了,最后查是否因TLS握手被网关拦截。
常见问题排查与规避
考生提交时Nginx返回499或408,怎么查?
这类错误通常发生在客户端断开连接之后,首先在Nginx的access log中查看upstream_response_time

,如果耗时普遍低于50ms但依然大量499,说明连接复用在客户端侧失效了,考生端页面在请求发出后过早跳转或关闭页面,解决方式是前端在交卷完成后不要立即跳转结果页,而是等fetch回调确认收到成功码后再跳转,同时确认服务端返回的Connection: keep-alive头没有被网关剥离。
连接池扩了但数据库连接仍然不够用?
多数情况是SQL语句在提交事务后未释放锁,查MySQL的information_schema.innodb_trx表,看是否有长期未提交的事务占着连接,在线模考提交场景常见的是:判分逻辑和提交事务放在一个事务里,导致事务执行时间过长,解决方案是把提交事务拆成多个小事务,提交记录、答案校验、判分结果分别独立提交。
本地模拟连接复用正常,上线后效果不明显?
区别通常出在DNS层面,部分考生所在网络的DNS解析出的CDN节点不支持HTTP/2,导致其回源到网关使用HTTP/1.1,检查CDN回源配置是否强制走HTTP/2,同时确认网关proxy_http_version是否为1.1。
连接复用方案要点回顾与问答
连接复用解决的不是“带宽不够”的问题,而是“连接数量过多”的问题,考试季在线模考提交高峰,通过连接池合理配置、HTTP/2多路复用、Keep-Alive超时三管齐下,结合超时熔断和异步判分,能有效保障高峰期提交成功率,大多数崩溃的系统,其实是被重复连接打垮的,复用逻辑治的是这个病根,上线前务必做全链路的压测,压测后的数据才是方案有效性的唯一凭证。
在线考试系统高并发连接复用方案是否会影响判分速度?
不会,连接复用只作用于网络传输层和连接池层面,判分逻辑是异步独立运行的,连接池的释放与判分的进程调度没有直接耦合关系,交卷成功后连接即被复用给下一位考生,判分任务进入消息队列陆续执行,真正影响判分速度的是后端消费者的核心数和队列长度,与连接复用方案无关。
HTTP连接复用和TCP连接池哪个适合在线模考场景?
两者服务于不同层级,考试系统需要同时用,浏览器端到网关用HTTP层连接复用(Keep-Alive或HTTP/2);后端考试服务到数据库、Redis用TCP连接池,如果只做TCP连接池而忽略前端HTTP复用,网关层和CDN层的膨胀连接数依然会打满端口,如果只做HTTP复用而数据库不配置连接池,后端服务会频繁短连数据库,照样拖垮数据库负载,两者属于配合关系而非替代关系。
考试系统keep-alive超时时间设置多久合适?
看链路位置分层设置,网关层建议65秒,后端服务建议30秒,前端侧如果使用了fetch提交,显式设置keepalive超时为至少30秒,不同位置的超时时间需要满足“递减或相等”的原则,网关超时不要大于后端,避免代理保持连接而后端早已断开,实际生产中还建议通过压测微调,因为不同的云服务商在底层LB的闲置连接断开时间上存在差异,需要避开这一层的隐性回收机制。