diff --git a/backend/services/alert.go b/backend/services/alert.go index 498ac83..ca316e7 100644 --- a/backend/services/alert.go +++ b/backend/services/alert.go @@ -48,7 +48,10 @@ func overStormLimit() (bool, int) { return sent >= alertStormMaxPerHour, sent } -const alertCheckInterval = time.Minute +// 检查间隔:规则窗口都是 15 分钟,1 分钟查一次等于用 15 倍频率扫同样的数据。 +// Loki 单实例 CPU 是瓶颈(实测被限流 76%),这里降到 5 分钟: +// 对告警及时性影响很小(窗口本身就是 15 分钟),但稳态负载降到 1/5。 +const alertCheckInterval = 5 * time.Minute const ( // alertRoundTimeout 一轮检查的总时限。超过就中断本轮, diff --git a/backend/services/log_query.go b/backend/services/log_query.go index 3886a0b..33e0348 100644 --- a/backend/services/log_query.go +++ b/backend/services/log_query.go @@ -367,11 +367,24 @@ func LokiLabels(ctx context.Context, src *models.LogSource, start, end int64) ([ } // LokiLabelValues 标签值列表(query 只取 {...} selector 部分) +// labelValuesDefaultWindow 是 label 值下拉框的默认时间窗。 +// 只影响"没显式给时间范围"的调用(下拉框),不影响带范围的查询。 +const labelValuesDefaultWindow = time.Hour + func LokiLabelValues(ctx context.Context, src *models.LogSource, name, selector string, start, end int64) ([]string, error) { q := url.Values{} if s := extractStreamSelector(selector); s != "" && s != "{}" { q.Set("query", s) } + // 不传时间范围时 Loki 默认扫**最近 6 小时**的索引 —— 在 370GB/天的集群上 + // 实测要 10~21 秒(下拉框"一直加载中"的直接原因)。 + // 下拉框只需要"现在有哪些 app/pod 在打日志",给 1 小时足够,索引量降到 1/6。 + // 调用方显式传了时间范围则完全尊从,不受影响。 + if start <= 0 && end <= 0 { + now := time.Now() + start = now.Add(-labelValuesDefaultWindow).UnixNano() + end = now.UnixNano() + } if end > 0 { q.Set("end", strconv.FormatInt(end, 10)) } diff --git a/backend/services/loki_config.go b/backend/services/loki_config.go index 483dc37..4fc3b52 100644 --- a/backend/services/loki_config.go +++ b/backend/services/loki_config.go @@ -70,7 +70,9 @@ compactor: limits_config: retention_period: {{ .RetentionPeriod }}h # 单实例 Loki 的并发护栏:默认 32 高得离谱,一条重查询就能把单进程打满 - max_query_parallelism: 8 + # 并行度不要超过实际 CPU 核数:超了只是让多个查询互相抢 CPU、 + # 每个都变慢(实测 4 核 + 并行 8 时限流 76%,label values 都要 20 秒)。 + max_query_parallelism: 6 # ── 查询结果缓存(官方推荐;此前完全没配,重复查询要重算一遍)─────── # align_queries_with_step 让不同时间范围的同类查询对齐到同一 step,