Skip to content

fix(dispatch): 連錯 Redis 還是靜默的——補啟動 log,並收掉兩個仍指向 6379 的地方 - #73

Merged
thothawei merged 1 commit into
mainfrom
claude/redis-silent-wrong-host
Aug 1, 2026
Merged

fix(dispatch): 連錯 Redis 還是靜默的——補啟動 log,並收掉兩個仍指向 6379 的地方#73
thothawei merged 1 commit into
mainfrom
claude/redis-silent-wrong-host

Conversation

@thothawei

Copy link
Copy Markdown
Owner

起因

#72 合併後回頭掃了一次 6379,發現兩個地方仍把人導回舊埠,而且更重要的是:#72 讓 docker 的 redis 讓開了埠號,但「這次到底連到哪一台」這個問題本身還是查不出來

根因一句話

連錯不會失敗——兩台都是健康的 redis,Ping 都會過,所以限流/派單狀態安安靜靜寫進了另一台,而你在容器裡 redis-cli KEYS 怎麼查都查不到,很容易誤判成「鍵根本沒寫進去」。埠號寫錯只是誘因,靜默才是病。

改了什麼

檔案 改動 為什麼
cmd/server/main.go ping 成功後 log.Info().Str("redis_addr", …) 本 PR 的重點。讓「連到哪一台」是一行 log,不是一小時的猜測。比照上面 DB 印 statement_timeout 的理由:ops 可見
internal/config/config.go 缺省 localhost:6379localhost:6380 這個缺省值只有「服務跑在主機、又忘了設 REDIS_ADDR」時才會用到——那正是會連錯台的情境。compose 內一律明設 REDIS_ADDR=redis:6379,不受影響
internal/config/config.go Load() 的註解更正 原本寫「缺省值對應本地 docker-compose」,其實對應的是「服務在主機、相依服務在 docker」那個跑法(compose 會把 DB_HOSTREDIS_ADDR 明設成服務名)。同一件事有兩種說法比沒寫更糟
scripts/push_e2e.sh 起服務註解 6379127.0.0.1:6380 照原註解做就會重現 #72 修掉的那個坑

為什麼缺省值也要改(而不是只改文件)

因為文件是「照著做才會對」,缺省值是「什麼都不做就會錯」。忘記設環境變數的人不會去讀 README——他會得到一個看起來完全正常、實際上寫到別台的服務。

驗收

  • gofmt 乾淨、go build ./... 通過、go vet ./... 無輸出、go test ./internal/config/ ok。
  • 新增 2 個 config 測試:缺省是 6380/明設 REDIS_ADDR 就照用(後者釘的是「缺省值的改動不可以影響 compose」)。
  • 反向驗證:把缺省值改回 localhost:6379 → 缺省那案 FAIL實際:localhost:6379),改回 6380 才綠。
  • ⚠️ 啟動 log 那一行只驗到編譯,沒有實跑觀察——起 server 會跑 migration,依「寫 DB 前先問過」的約定沒有自己跑。要補這段實跑證據隨時可以,說一聲就好。

🤖 Generated with Claude Code

#72 讓 docker 的 redis 對外發布 6380,但「連到哪一台」這個問題本身還是查不出來,
而且有兩個地方仍把人導回 6379:

1. `scripts/push_e2e.sh` 的起服務註解寫 `REDIS_ADDR=localhost:6379`——照著做就會
   重現 #72 修掉的那個坑(靜默連到 Mac 本機的 redis-server)。改成 6380 並寫明理由。
2. `config.Load()` 的缺省值是 `localhost:6379`。這個缺省值只有「服務跑在主機、
   又忘了設 REDIS_ADDR」時才會用到——那正是會連錯台的情境。改成 6380。
   docker compose 內一律明設 `REDIS_ADDR=redis:6379`,不受這行影響。
   順帶更正 `Load()` 的註解:缺省值對應的是「服務在主機、相依服務在 docker」的
   本地跑法,不是 compose 內部(compose 會把 DB_HOST/REDIS_ADDR 明設成服務名)。

但真正的根因不是埠號寫錯,是**連錯不會失敗**:兩台都是健康的 redis,ping 都會過,
於是限流/派單狀態寫進了另一台,而你在容器裡怎麼查都查不到。所以最重要的一行是
ping 成功之後把位址印出來(比照 DB 印 statement_timeout 的理由:ops 可見)——
讓「連到哪一台」變成一行 log,而不是一小時的猜測。

驗收:gofmt 乾淨、go build ./... 通過、go vet ./... 無輸出、
go test ./internal/config/ ok。新增 2 個 config 測試(缺省 6380/明設就照用),
反向驗證:把缺省值改回 6379,缺省那案 FAIL。
啟動 log 那一行只驗到編譯,**沒有實跑觀察**——起 server 會跑 migration,依約定要先問過。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thothawei
thothawei merged commit 3bd5407 into main Aug 1, 2026
1 check passed
@thothawei
thothawei deleted the claude/redis-silent-wrong-host branch August 1, 2026 10:45
@thothawei

Copy link
Copy Markdown
Owner Author

補上實跑證據:PR 內文寫的「啟動 log 只驗到編譯,沒有實跑觀察」現在過期了,以本則為準

合併後補跑了。剛好本機那台 redis-server 還在 6379 聽著,所以做得成真正的對照組——這比原本打算的「起來看一眼有沒有印」有用得多。

前置:先證明是兩台不同的 redis

不靠 redis-cli 的預設連法(它自己就會挑錯台),改用 raw socket 對兩個埠各寫一個識別鍵:

位址 GET whoami
127.0.0.1:6379 host_redis(Mac 常駐的 redis-server)
127.0.0.1:6380 docker_redis_6380(compose 起的那台)

lsof -nP -iTCP:6379 -sTCP:LISTEN 也確認 redis-ser 綁在 127.0.0.1:6379

三種跑法各起一次 server,log 都指認正確

docker compose up -d postgis redis + server 跑在主機)

跑法 啟動 log
A:REDIS_ADDR=127.0.0.1:6380 INF 已連線 Redis redis_addr=127.0.0.1:6380
B:REDIS_ADDR=127.0.0.1:6379故意連錯台 INF 已連線 Redis redis_addr=127.0.0.1:6379
C:完全不設 REDIS_ADDR INF 已連線 Redis redis_addr=localhost:6380

C 這條順帶把缺省值那個改動驗成端到端——不只是單元測試裡的字串比對,是真的沒設環境變數時服務會連到 docker 那台。

B 那次才是這行 log 存在的理由

連到錯的那台之後:

  • 整份啟動 log 的錯誤級別行數是 0grep -icE "ERR|FTL|failed|失敗"0
  • 服務完整起來了[GIN-debug] Listening and serving HTTP on :8080

也就是說,補這行之前「連錯台」和「連對台」在畫面上長得一模一樣:狀態安靜地寫進另一台,你只能靠猜(#72 當初就是這樣繞了一圈)。現在那一行就是答案。

收尾

三個 server 程序都已結束、寫進兩台 redis 的 whoami 測試鍵都刪掉(各回 :1)、docker compose down 已執行(容器與網路移除,postgis volume 保留)。第一次啟動有跑 migration。

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant