diff --git a/cmd/server/main.go b/cmd/server/main.go index f4b68a1..c2a1815 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -62,6 +62,12 @@ func main() { if err := redisClient.Ping(context.Background()).Err(); err != nil { log.Fatal().Err(err).Msg("連線 Redis 失敗") } + // **連錯台不會失敗**:開發機上常有第二個 redis 在聽(Mac 的 redis-server 綁 + // 127.0.0.1:6379,比 docker 的 *:6379 精確而優先接手),兩台都 ping 得通, + // 於是限流/派單狀態寫進了另一台,而你在容器裡怎麼查都查不到。 + // ping 成功時把位址印出來,讓「連到哪一台」是一行 log 而不是一小時的猜測 + // (比照上面 DB 印 statement_timeout 的理由:ops 可見)。 + log.Info().Str("redis_addr", cfg.RedisAddr).Msg("已連線 Redis") // Repositories customerRepo := repository.NewCustomerRepository(db) diff --git a/internal/config/config.go b/internal/config/config.go index a866b6c..563de1c 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -58,19 +58,26 @@ type Config struct { FCMCredentialsFile string } -// Load 讀取環境變數,缺省值對應本地 docker-compose +// Load 讀取環境變數。 +// +// 缺省值對應的是「**服務跑在主機、相依服務跑在 docker**」這個本地開發跑法, +// 不是 compose 內部(compose 會把 DB_HOST、REDIS_ADDR 等明設成服務名)。 +// 所以 Redis 缺省是 docker 對外發布的 6380,不是 redis 的標準埠 6379——理由見該行。 func Load() (*Config, error) { cfg := &Config{ - AppPort: getEnvInt("APP_PORT", 8080), - AppEnv: getEnv("APP_ENV", "local"), - LogLevel: getEnv("LOG_LEVEL", "info"), - DBHost: getEnv("DB_HOST", "localhost"), - DBPort: getEnvInt("DB_PORT", 5432), - DBName: getEnv("DB_NAME", "fleet"), - DBUser: getEnv("DB_USER", "fleet"), - DBPassword: getEnv("DB_PASSWORD", "change_me"), - DBStatementTimeoutMs: getEnvInt("DB_STATEMENT_TIMEOUT_MS", 10000), - RedisAddr: getEnv("REDIS_ADDR", "localhost:6379"), + AppPort: getEnvInt("APP_PORT", 8080), + AppEnv: getEnv("APP_ENV", "local"), + LogLevel: getEnv("LOG_LEVEL", "info"), + DBHost: getEnv("DB_HOST", "localhost"), + DBPort: getEnvInt("DB_PORT", 5432), + DBName: getEnv("DB_NAME", "fleet"), + DBUser: getEnv("DB_USER", "fleet"), + DBPassword: getEnv("DB_PASSWORD", "change_me"), + DBStatementTimeoutMs: getEnvInt("DB_STATEMENT_TIMEOUT_MS", 10000), + // 預設 6380 而不是 6379:這個缺省值只有「服務跑在主機、又沒設 REDIS_ADDR」時才會用到, + // 而那正是會靜默連到開發者自己那台 redis-server 的情境(見 docker-compose 的說明)。 + // docker compose 內一律明設 REDIS_ADDR=redis:6379,不受這行影響。 + RedisAddr: getEnv("REDIS_ADDR", "localhost:6380"), LineChannelSecret: getEnv("LINE_CHANNEL_SECRET", ""), LineChannelAccessToken: getEnv("LINE_CHANNEL_ACCESS_TOKEN", ""), LiffID: getEnv("LIFF_ID", ""), diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 9bb5e57..5018b4f 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -33,3 +33,32 @@ func TestMigrateDSN_不受statement_timeout影響(t *testing.T) { t.Fatalf("migrations 連線不應套用 statement_timeout:%s", c.MigrateDSN()) } } + +// 沒設 REDIS_ADDR 時的缺省值刻意是 6380,不是 redis 的標準埠 6379。 +// +// 這個缺省值只有「服務跑在主機、又忘了設 REDIS_ADDR」時才會用到,而那正是會靜默連到 +// 開發機自己那台 redis-server 的情境:兩台都 ping 得通,所以不會有任何錯誤, +// 只會讓限流/派單狀態寫進另一台,在容器裡怎麼查都查不到(見 docker-compose 的說明)。 +// 這條測試釘的是那個決定——看到 6380 覺得「怪,改回標準埠吧」的人會在這裡被擋下來。 +func TestLoad_Redis缺省埠是6380而非6379(t *testing.T) { + t.Setenv("REDIS_ADDR", "") + cfg, err := Load() + if err != nil { + t.Fatalf("Load 失敗:%v", err) + } + if cfg.RedisAddr != "localhost:6380" { + t.Fatalf("缺省 RedisAddr 應為 localhost:6380(避開本機 redis-server 的 6379),實際:%s", cfg.RedisAddr) + } +} + +func TestLoad_有設REDIS_ADDR就照用(t *testing.T) { + t.Setenv("REDIS_ADDR", "redis:6379") + cfg, err := Load() + if err != nil { + t.Fatalf("Load 失敗:%v", err) + } + // docker compose 內就是這個值——缺省值的改動不可以影響已明設的情況。 + if cfg.RedisAddr != "redis:6379" { + t.Fatalf("明設 REDIS_ADDR 應照用,實際:%s", cfg.RedisAddr) + } +} diff --git a/scripts/push_e2e.sh b/scripts/push_e2e.sh index 861eed3..6b30b1d 100755 --- a/scripts/push_e2e.sh +++ b/scripts/push_e2e.sh @@ -8,8 +8,11 @@ # load metadata for golang:1.25-alpine,改用這條): # docker compose up -d postgis redis # DB_HOST=localhost DB_PORT=5433 DB_NAME=fleet DB_USER=fleet DB_PASSWORD=change_me \ -# REDIS_ADDR=localhost:6379 ADMIN_SEED_USERNAME=admin ADMIN_SEED_PASSWORD=admin \ +# REDIS_ADDR=127.0.0.1:6380 ADMIN_SEED_USERNAME=admin ADMIN_SEED_PASSWORD=admin \ # go run ./cmd/server > /tmp/push_server.log 2>&1 & +# **Redis 要 6380 不要 6379**:Mac 上常駐的 redis-server 綁 127.0.0.1:6379,比 docker 的 +# *:6379 精確,localhost 一律由它接手——連錯不會報錯(兩台都 ping 得通),只會讓你在容器裡 +# 查不到任何鍵,誤判成「限流/狀態根本沒寫進去」。啟動 log 的 redis_addr 會說這次連了哪台。 # 跑完看證據: # grep 'App 推播(stub)' /tmp/push_server.log set -e