[Bug] Website statistics queue cursor is not initialized, causing worker 0 to periodically scan historical sequence numbers and block requests
Maintainer thường phản hồi trong vòng 1 ngày
@zhengkunwang223 đang làm issue này rồi.
Từ ngày 14/10/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
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 字节码及运行时状态发现:
- worker 0 每 3 秒调用
monitor_task.insert_log。 - 任务从
ngx.shared.waf读取<site>_sql_start,缺失时以局部值 1 作为循环起点。 - 循环中直接调用
incr(key, 1),没有先初始化共享字典中的键,也没有处理递增失败。 - 对不存在的键执行 incr 不会创建键,因此共享游标始终为 nil,每轮重新遍历
1..累计序号。 - 已消费并删除的队列记录仍被反复查找,同步循环阻塞处理 HTTP 请求的 worker。
现场某站点累计序号为 1,555,625,游标仍为 nil。无新增请求时,任务仍反复耗时约 2.6–2.8 秒;探针另观察到 5.06 秒、8.61 秒的调用耗时,其中可能包含锁等待。
Steps to Reproduce
- 使用上述镜像,开启网站访问统计。
- 持续正常访问站点,使统计队列累计序号增长,无需维持高并发。
- 检查 worker 0 CPU 和 HTTP 首字节等待时间。
- 在统计任务中读取共享字典,比较
<site>_sql与<site>_sql_start。本现场累计序号超过 155 万,而游标为 nil。 - 停止新增流量,观察统计任务仍每 3 秒反复执行约 2.6–2.8 秒。
- 首次消费前初始化缺失游标,再对比 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 索引,本次则为共享字典游标缺失。
- Ngôn ngữ chính
- Go
- Star
- 37.1k
- Fork
- 3.4k
- Merge trung bình
- 11 giờ 40 phút
- Pull request đã merge (30 ngày)
- 95
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của 1Panel-dev/1Panel
-
[Feature] 防跨站攻击增加PHP_ADMIN_VALUE配置Có thể đã có người làm @wanghe-fit2cloud đã nhận hôm nay. Đang mở
1Panel-dev/1Panel#14112 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Feature] 增加批量修改网站PHP版本的功能Có thể đã có người làm @wanghe-fit2cloud đã nhận hôm nay. Đang mở
1Panel-dev/1Panel#14111 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Feature] 应用商店增加 WeKnoraCó thể đã có người làm @wanghe-fit2cloud đã nhận hôm nay. Đang mở
1Panel-dev/1Panel#14110 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Feature] 任务中心终止任务Có thể đã có người làm @wanghe-fit2cloud đã nhận hôm nay. Đang mở
1Panel-dev/1Panel#14107 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug] docker拉取镜像失败Có thể đã có người làm @wanghe-fit2cloud đã nhận 1 ngày trước. Đang mở
1Panel-dev/1Panel#14106 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của 1Panel-dev/1Panel
Issue tương tự
-
documentation hacktoberfest priority: low skill: good first issue status: ready for dev
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 85/100
hyperledger-labs/fabric-smart-client#2142 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
numberly/vault-db-injector#107 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area/import kind/bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[DOC] Wrong sg_egress_ports range in the Terraform Databricks Guide for AWS Hub & Spoke with Network FirewallCó thể đã có người làm @akhil9tiet đã nhận hôm nay. Đang mởdocs
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 72/100
databricks/terraform-provider-databricks#6080 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
spqr-coordinator usage shows 'run --config', but 'run' is not a subcommand (unknown command "run")Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
pg-sharding/spqr#3092 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày