一、故障基本信息

  • 故障时间:2026 年 04 月 16 日

  • 故障现象:Halo 2.21.9 博客无法访问,报错 Request queue limit reached(数据库请求队列已满);凌晨执行备份操作未生成备份文件,修改设置 / 安装插件后可正常访问,当日早间突发故障

  • 影响范围:Halo 博客全站无法访问,用户无法正常浏览、后台无法登录

  • 技术栈:1Panel 一键部署 Halo 2.21.9(Spring WebFlux 响应式架构)、MariaDB R2DBC 驱动、Docker 容器化部署


二、故障根因分析

1. 核心故障本质

本次故障并非高并发访问导致,而是「低访问量下的连接池 / 队列缓慢耗尽」,核心原因如下:

  1. 备份任务异常卡死,连接长期不释放:凌晨备份操作失败未生成文件,备份线程持续占用数据库连接,导致 R2DBC 驱动请求队列逐步被占满

  2. 驱动默认队列阈值过小:MariaDB R2DBC 驱动默认 requestQueueSize 仅为 16,Halo 单页面加载即产生 5~15 个并发数据库查询,叠加后台定时任务、插件操作,极易触发队列满

  3. 插件 / 设置修改加剧队列消耗:新增插件、修改博客设置产生额外数据库读写,进一步消耗队列资源,最终在凌晨操作后至当日早间彻底耗尽队列,导致服务不可用

2. 故障时间线

表格

时间节点

操作 / 现象

影响

04 月 16 日凌晨

执行 Halo 备份操作,未生成备份文件(备份任务卡死)

数据库连接被占用,队列开始累积

04 月 16 日凌晨

修改博客设置、安装新插件

新增数据库读写,队列持续消耗

04 月 16 日凌晨

博客可正常访问

队列未完全耗尽,服务临时可用

04 月 16 日早间

博客无法访问,报 Request queue limit reached 错误

队列彻底满,服务完全不可用


三、故障解决过程(关键步骤)

1. 紧急恢复(优先执行)

  • 操作:在 1Panel 应用列表中,停止 Halo 容器后重新启动,同步重启 MariaDB 数据库

  • 效果:清空卡死的数据库连接与请求队列,快速恢复博客访问

  • 原理:重启释放所有被占用的连接,解决队列「假满」问题

2. 根治配置优化(一劳永逸)

  • 操作:在 1Panel「参数配置→高级设置→编辑 compose 文件」中,修改 Halo 数据库 URL,添加队列参数:

    yaml

    --spring.r2dbc.url=r2dbc:pool:${PANEL_DB_TYPE}://${PANEL_DB_HOST}:${PANEL_DB_PORT}/${PANEL_DB_NAME}?requestQueueSize=128
    
  • 操作后续:保存配置后重建 Halo 应用,使配置生效

  • 效果:将驱动请求队列从默认 16 扩容至 128,彻底避免低访问量下的队列满问题

  • 原理:扩容队列后,单页面并发查询、后台任务不会再触发队列溢出,从根源解决故障

3. 辅助优化(防止复发)

  • 清理 Halo 后台失败的备份记录,避免备份任务重复卡死

  • 临时禁用新增插件,排查插件导致的慢查询 / 连接占用问题

  • 调整自动备份频率,降低后台任务对数据库的持续消耗


四、故障验证与预防

1. 故障验证

  • 重启后博客可正常访问,无 Request queue limit reached 报错

  • 配置修改并重建应用后,多次刷新页面、后台操作均无异常,服务稳定

  • 后续备份操作正常生成文件,无卡死情况

2. 预防措施

  1. 定期重启服务:低访问量场景下,定期重启 Halo 可释放卡死连接,避免队列累积

  2. 优化备份策略:避免频繁自动备份,备份时避开业务高峰,备份后验证文件生成

  3. 插件管理:谨慎安装第三方插件,新增插件后观察服务稳定性,及时禁用异常插件

  4. 配置固化:保持 requestQueueSize=128 的优化配置,避免恢复默认值


五、总结

本次故障为 Halo 2.21.9 响应式架构 + R2DBC 驱动默认配置缺陷 + 备份任务卡死 共同导致的「低访问量队列满」问题,并非外部高并发攻击。通过「紧急重启恢复 + 扩容队列根治 + 辅助优化防复发」的方案,已彻底解决故障,博客服务恢复稳定。