fix: cache tenant routing on message hot path

This commit is contained in:
richjohnrambo
2026-09-27 20:10:18 +08:00
parent 36b52e120c
commit 8e778726e0
12 changed files with 196 additions and 44 deletions
+1 -1
View File
@@ -145,7 +145,7 @@ mkdir -p "loadtest/im-pressure/results/${RUN_ID}"
2. agent 向机器 A coordinator 报告 READY。
3. 如果机器 A 尚未 READY,当前命令会等待,这是正常现象。
4. coordinator 下发 `run_id`、场景和统一 UTC 开始时间。
5. agent 完成发送、WS 到达统计、drain 和历史持久化回查。
5. agent 完成发送和 WS 到达统计,等待 `history_settle`(默认 5 分钟)后,再以有界并发执行历史持久化回查;等待期间不要停止进程。
6. agent 写出 summary、上报 coordinator,然后正常退出。
机器 B 不需要传场景参数。`p2p`、`group` 或 `mixed` 由机器 A coordinator 决定。
+2 -2
View File
@@ -47,9 +47,9 @@
- 发送成功以 `{ctrl code=2xx, params.seq>0}` 为准,形成两台机器共享的 ACK 台账。
- 实时到达只统计同时匹配本轮 `run_id` 和 `x-im-client-mid` 的 `{data}`。
- 群消息设置 `noecho=false`,每条服务端接受的群消息期望 2000 个连接各收到一次。
- 实时 drain 结束后通过 `{get what=data}` 按 ACK 的 Topic/Seq 回查历史,区分跨 Pod 实时漏投与数据库持久化缺失。
- 实时 drain 结束后先等待 `history_settle`(默认 5 分钟),让 Kafka 在不受核验查询干扰的情况下自然排空,再通过 `{get what=data}` 按 ACK 的 Topic/Seq 回查历史。
- 每轮建立 WS 后、正式计时前,以 32 个 worker 对本机 1000 个账号做好友关系、P2P Topic 和发布权限预检;任一异常会终止本轮。
- 历史回查默认使用 48 个 worker、总超时 3 分钟,并对缺失项再并发重试两轮。
- 历史回查默认每机使用 12 个 worker、总超时 3 分钟,并在超时内持续重试缺失区间。历史读取并发能力应使用独立场景测试,不与落库吞吐测试混在一起。
- publish 错误完整分类为 `403`、`502`、`503`、`ctrl_timeout`、`socket_error` 和 `other`,不受文本错误样本上限影响。
- `manifest.json` 含登录 token,文件权限为 `0600`,不得提交到 Git 或放入结果包。
+5
View File
@@ -183,6 +183,11 @@ func runAgent(ctx context.Context, cfg *Config, manifest *Manifest, machine, coo
base.Errors = append(base.Errors, run.errors...)
run.mu.Unlock()
summary := run.recorder.summarize(base, ledger)
historySettle, _ := configDuration(cfg.HistorySettle)
log.Printf("agent=%s waiting %s before history verification", machine, historySettle)
if err = waitContext(ctx, historySettle); err != nil {
return err
}
checked, found, persistenceMissing := run.reconcileHistory(ctx, ledger)
summary.HistoryChecked = int64(checked)
summary.HistoryFound = int64(found)
+2 -1
View File
@@ -16,7 +16,8 @@
"command_timeout": "20s",
"preflight_workers": 32,
"skip_p2p_preflight": false,
"history_workers": 48,
"history_workers": 12,
"history_settle": "5m",
"history_timeout": "3m",
"p2p_messages_per_user": 10,
"p2p_interval": "1s",
+8 -1
View File
@@ -32,6 +32,7 @@ type Config struct {
PhonePrefix string `json:"registration_phone_prefix"`
VerifyCodeEnv string `json:"verification_code_env"`
HistoryWorkers int `json:"history_workers"`
HistorySettle string `json:"history_settle"`
HistoryTimeout string `json:"history_timeout"`
PreflightWorkers int `json:"preflight_workers"`
SkipP2PPreflight bool `json:"skip_p2p_preflight"`
@@ -74,7 +75,7 @@ func loadConfig(path string) (*Config, error) {
cfg.DrainGroup = "60s"
}
if cfg.HistoryWorkers <= 0 {
cfg.HistoryWorkers = 48
cfg.HistoryWorkers = 12
}
if cfg.HistoryWorkers > 128 {
return nil, errors.New("history_workers must not exceed 128")
@@ -82,6 +83,12 @@ func loadConfig(path string) (*Config, error) {
if cfg.HistoryTimeout == "" {
cfg.HistoryTimeout = "3m"
}
if cfg.HistorySettle == "" {
cfg.HistorySettle = "5m"
}
if _, err = configDuration(cfg.HistorySettle); err != nil {
return nil, fmt.Errorf("history_settle: %w", err)
}
if _, err = configDuration(cfg.HistoryTimeout); err != nil {
return nil, fmt.Errorf("history_timeout: %w", err)
}
+1 -1
View File
@@ -16,7 +16,7 @@ func TestLoadConfigAppliesBoundedHistoryDefaults(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if cfg.HistoryWorkers != 48 || cfg.HistoryTimeout != "3m" || cfg.PreflightWorkers != 32 {
if cfg.HistoryWorkers != 12 || cfg.HistorySettle != "5m" || cfg.HistoryTimeout != "3m" || cfg.PreflightWorkers != 32 {
t.Fatalf("unexpected defaults: %+v", cfg)
}
}