3x-ui/docs/Tasktracking/2026-04-24-fix-traffic-flush-blocked-by-stale-delta.md
root eca9b219cf docs: add missing task tracking records for multi-node and traffic fixes
Add task tracking records for commits that were missing documentation:
- 2026-04-10: multi-node backend foundation (7 commits)
- 2026-04-15: improve mariadb flow and traffic flush
- 2026-04-23: install cron before acme.sh
- 2026-04-24: resolve client traffic InboundId from DB
- 2026-04-24: fix traffic flush blocked by stale inboundId=0 delta
2026-04-24 03:04:15 +08:00

42 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Task Record: Resolve shared-mode traffic flush blocked by stale inboundId=0 delta
Date: 2026-04-24
Related Module: web/service/traffic_flush.go, web/web.go, web/job/xray_traffic_job.go — 流量刷盘
Change Type: Fix
Background
共享模式下流量统计始终为 0MariaDB 的 `client_traffics` 表从未被写入。排查发现 `traffic-pending.json` 中存在一个残留的 `inboundId: 0` 客户端流量 delta在 InboundId 解析修复前产生)。`flushToDatabase()` 尝试将其写入 `client_traffics` 时,违反外键约束 `fk_inbounds_client_stats``inbounds` 表不存在 `id=0`),导致整个事务回滚,所有流量永远无法写入。
此外,`NewXrayTrafficJob()` 和 `startTrafficFlushLoop()` 各自创建了独立的 `TrafficPendingStore` 实例,指向同一个 `traffic-pending.json` 文件但使用独立的 `sync.Mutex`,存在数据竞争风险。
Changes
- `web/service/traffic_flush.go`:
- `flushToDatabase()` 循环开头新增 `InboundID == 0` 检查,跳过无效 delta 并记录 warning 日志
- `web/job/xray_traffic_job.go`:
- `NewXrayTrafficJob()` 改为接受 `*service.TrafficPendingStore` 参数,不再自行创建 store
- 移除 `config` 包依赖
- `web/web.go`:
- `Server` struct 新增 `trafficStore *service.TrafficPendingStore` 字段
- `Start()` 中统一创建一个 `TrafficPendingStore` 实例
- `startTask()``startTrafficFlushLoop()` 共享同一个 store 实例,消除双实例竞争
- `web/service/traffic_flush_test.go`:
- 新增 `TestFlushOnceSkipsZeroInboundIdDelta` 测试
Impact
- `web/service/traffic_flush.go`: flushToDatabase() 跳过无效 delta
- `web/web.go`: Server 启动流程变更store 统一创建
- `web/job/xray_traffic_job.go`: 构造函数签名变更
- 修复后需要删除残留的 `traffic-pending.json` 文件才能生效
Verification
- `go test ./web/service/ -run TestTraffic -v` — PASS
- `go test ./web/service/ -run TestFlushOnceSkipsZeroInboundIdDelta -v` — PASS
Risks And Follow-Up
- 部署时必须删除 `/etc/x-ui/traffic-pending.json`,否则残留的 `inboundId: 0` delta 仍会被跳过(不影响功能,但会产生 warning 日志)
- `TrafficPendingStore` 的文件级锁已通过共享实例解决,但如果未来有多个进程访问同一文件,仍需考虑进程级锁