Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

[Bug] Website statistics queue cursor is not initialized, causing worker 0 to periodically scan historical sequence numbers and block requests

Abierto
#14,028 0 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@wanghe-fit2cloud ya está trabajando en esto.

Desde el 11/10/2026.

Evaluación

Este issue todavía no se ha evaluado.

Descripción

type: question
Contact Information

No response

1Panel Version

v1.10.34-lts stable

Problem Description
  • OpenResty 镜像:1panel/openresty:1.21.4.3-3-3-focal
  • 内置 1Panel WAF:1.0.0
  • 网站访问统计:开启
  • 请求链路:浏览器 → OpenResty → Nginx gateway → Node.js WMS

网站累计大量请求后,OpenResty 单个 worker 持续占用约 70–80% CPU,部分 HTTP 请求首字节等待超过 6 秒,而后端实际处理仅需毫秒。服务器本机重放也曾测到 13.44 秒首字节等待。

检查当前镜像的 Lua 字节码及运行时状态发现:

  1. worker 0 每 3 秒调用 monitor_task.insert_log。
  2. 任务从 ngx.shared.waf 读取 <site>_sql_start,缺失时以局部值 1 作为循环起点。
  3. 循环中直接调用 incr(key, 1),没有先初始化共享字典中的键,也没有处理递增失败。
  4. 对不存在的键执行 incr 不会创建键,因此共享游标始终为 nil,每轮重新遍历 1..累计序号。
  5. 已消费并删除的队列记录仍被反复查找,同步循环阻塞处理 HTTP 请求的 worker。

现场某站点累计序号为 1,555,625,游标仍为 nil。无新增请求时,任务仍反复耗时约 2.6–2.8 秒;探针另观察到 5.06 秒、8.61 秒的调用耗时,其中可能包含锁等待。

Steps to Reproduce
  1. 使用上述镜像,开启网站访问统计。
  2. 持续正常访问站点,使统计队列累计序号增长,无需维持高并发。
  3. 检查 worker 0 CPU 和 HTTP 首字节等待时间。
  4. 在统计任务中读取共享字典,比较 <site>_sql 与 <site>_sql_start。本现场累计序号超过 155 万,而游标为 nil。
  5. 停止新增流量,观察统计任务仍每 3 秒反复执行约 2.6–2.8 秒。
  6. 首次消费前初始化缺失游标,再对比 CPU 和请求延迟。
The expected correct result

首次消费前应安全初始化游标,检查共享字典操作结果。后续只处理未消费记录,不能随累计历史序号反复扫描。

建议回归覆盖:游标缺失恢复、已有游标保留、新记录继续消费、共享内存不足处理,以及 reload/共享内存重建。进一步建议限制每轮消费数量或执行时间,避免统计任务长时间占用请求 worker。

Related log output
以下为脱敏摘录,任务耗时由临时包装器在调用前后更新 ngx 时间后测量:


site_sql=1555625
site_sql_start=nil
worker=0 task=monitor_task.insert_log elapsed_ms=2745
worker=0 task=monitor_task.insert_log elapsed_ms=8614
worker=0 task=monitor_task.insert_log elapsed_ms=2789

某次本机重放的 OpenResty 日志:
request_time=6.943s
upstream_connect_time=4.282s
upstream_header_time=6.943s
Server-Timing: auth;dur=0.5, total;dur=0.6


Nginx 阶段时间由 worker 观察,worker 停顿会延迟事件处理,不能直接认定本机 TCP 建连实际花了 4.282 秒。
Additional Information

现场兼容补丁在原统计任务前初始化缺失游标,再执行厂商原有 worker.lua,保留其任务、锁和定时器:

if ngx.worker.id() == 0 then
    local config = require("config")
    local monitor = require("monitor_task")
    local insert_log = monitor.insert_log
    monitor.insert_log = function(...)
        for _, site in ipairs(config.get_website_keys() or {}) do
            local key = site .. "_sql_start"
            if ngx.shared.waf:get(key) == nil then
                local ok, err = ngx.shared.waf:safe_add(key, 1)
                if not ok and err ~= "exists" then
                    ngx.log(ngx.ERR, "WAF monitor cursor initialization failed: ", err)
                    return
                end
            end
        end
        return insert_log(...)
    end
end
dofile("/usr/local/openresty/1pwaf/worker.lua")

从 1 恢复以保留仍待消费的队列项,首次仍需追赶历史序号,此后游标正常前进。未清空队列或数据库,未停用 WAF。

修复后:

  • OpenResty CPU 一次采样降至 0.14%,后续另一次采样为 3.21%。
  • 初始化恢复完成后,未再观察到超过探针阈值 250 ms 的统计任务;新增访问仍正常写入数据库。
  • 服务器分层验证 320 次有效 WMS 请求全部返回 200。
  • Windows 全新 Edge 上下文通过 HTTP/2 实际加载、拖动、缩放地图,637 次 WMS 请求全部返回 200,无失败或取消,无浏览器磁盘缓存命中。
  • 浏览器等待响应 P95 423.44 ms,最大 901.29 ms,无超过 1 秒的样本;样本包含 WMS 能力查询。
  • 最慢首次请求后端 auth=471.8 ms、asset=399.6 ms、total=872.1 ms,与浏览器等待基本吻合。

这是短时回归,不代表所有网络或负载的延迟上限

类似现象:#13583,涉及 worker 0 的日志任务高 CPU,但其根因是 SQLite event_id 索引,本次则为共享字典游标缺失。

Lenguaje dominante
Go
Estrellas
37.1k
Forks
3.4k
Merge medio
13 h
PR fusionados (30 d)
82

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de 1Panel-dev/1Panel

Todos los issues de 1Panel-dev/1Panel

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.