From 1a08949c80cd1697f236a6aed2736efc925ba8ec Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Sat, 28 Mar 2026 18:36:13 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B5=81=E9=87=8F=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E9=99=90=E9=80=9F=E5=90=8E=E4=B8=BB=E5=8A=A8=E6=B8=85=E9=99=A4?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E7=94=A8=E6=88=B7=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 节点用户列表缓存(server:user:{id})永不过期,用户流量超限触发按量限速后 缓存中仍是旧的速度值,节点不会感知限速状态。 修复:每次写入 traffic_log 后,检查该订阅是否触发按量限速规则, 若 IsThrottled=true 则立即删除对应节点的用户列表缓存, 节点下次拉取时重新计算并应用降速后的 speed_limit。 Co-Authored-By: claude-flow --- queue/logic/traffic/trafficStatisticsLogic.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/queue/logic/traffic/trafficStatisticsLogic.go b/queue/logic/traffic/trafficStatisticsLogic.go index a89df57..9c5e9b1 100644 --- a/queue/logic/traffic/trafficStatisticsLogic.go +++ b/queue/logic/traffic/trafficStatisticsLogic.go @@ -3,11 +3,13 @@ package traffic import ( "context" "encoding/json" + "fmt" "strings" "time" "github.com/perfect-panel/server/internal/model/node" "github.com/perfect-panel/server/pkg/logger" + "github.com/perfect-panel/server/pkg/speedlimit" "github.com/hibiken/asynq" "github.com/perfect-panel/server/internal/model/traffic" @@ -126,6 +128,21 @@ func (l *TrafficStatisticsLogic) ProcessTask(ctx context.Context, task *asynq.Ta logger.Field("error", err.Error()), ) } + + // 写完流量后检查是否触发按量限速,若触发则清除节点缓存使限速立即生效 + if planSub, planErr := l.svc.SubscribeModel.FindOne(ctx, sub.SubscribeId); planErr == nil && + (planSub.SpeedLimit > 0 || planSub.TrafficLimit != "") { + throttle := speedlimit.Calculate(ctx, l.svc.DB, sub.UserId, sub.Id, planSub.SpeedLimit, planSub.TrafficLimit) + if throttle.IsThrottled { + cacheKey := fmt.Sprintf("%s%d", node.ServerUserListCacheKey, payload.ServerId) + if delErr := l.svc.Redis.Del(ctx, cacheKey).Err(); delErr != nil { + logger.WithContext(ctx).Error("[TrafficStatistics] Clear server user cache failed", + logger.Field("serverId", payload.ServerId), + logger.Field("error", delErr.Error()), + ) + } + } + } } return nil }