242 lines
7.8 KiB
Markdown
242 lines
7.8 KiB
Markdown
# gateway.yaml 設定說明
|
||
|
||
Gateway 使用 [go-zero `conf`](https://go-zero.dev/docs/tutorials/go-zero/configuration/overview) 載入 YAML。結構定義在 `internal/config/config.go`,對應各模組的 `Conf` 結構。
|
||
|
||
## 用哪個檔案?
|
||
|
||
| 檔案 | 是否提交 git | 用途 |
|
||
|------|:------------:|------|
|
||
| **`gateway.yaml`** | ✅ | 預設:不需 Docker,僅 health |
|
||
| **`gateway.dev.example.yaml`** | ✅ | 本機完整功能範例(無真實帳密) |
|
||
| **`gateway.dev.yaml`** | ❌ **勿提交** | 你的本機設定(Port、DB、SMTP/SES/三竹帳密) |
|
||
|
||
```bash
|
||
# 第一次本機開發
|
||
cp etc/gateway.dev.example.yaml etc/gateway.dev.yaml
|
||
# 編輯 etc/gateway.dev.yaml(例如 Port、Mitake 帳密)— 此檔已在 .gitignore
|
||
|
||
make deps-up
|
||
make mongo-index
|
||
make run-dev # 會自動 setup-dev(缺檔時從 example 複製)
|
||
|
||
# 僅 API(不需 gateway.dev.yaml)
|
||
make run
|
||
```
|
||
|
||
---
|
||
|
||
## go-zero 填寫規則(重要)
|
||
|
||
1. **欄位名稱必須與 Go struct 一致**(駝峰在 yaml 裡通常照抄,如 `MaxPoolSize`)。**不要**填 struct 裡沒有的欄位(例如以前的 `MaxStaleness`),否則可能觸發奇怪錯誤。
|
||
2. **沒標 `optional` 的頂層欄位**:在該區塊出現時需型別正確;我們已在 Mongo / Notification / Member 加上 `json:",optional"`,多數子欄位可省略。
|
||
3. **空字串 `""`**:可寫,表示無帳密 / 無 AuthSource。
|
||
4. **時間**:`30m`、`10s`(`time.Duration`)。
|
||
5. **字串陣列**(如 `Compressors`)必須是 YAML 列表,**不能**寫成單一字串:
|
||
```yaml
|
||
Compressors:
|
||
- zstd
|
||
- snappy
|
||
```
|
||
6. **Mongo 埠號**:用整數 `Port: 27017`,不要 `Port: "27017"`;或直接在 `Host` 寫 `127.0.0.1:27017`。
|
||
|
||
---
|
||
|
||
## 頂層:HTTP 服務(`rest.RestConf`)
|
||
|
||
| 欄位 | 必填 | 說明 | 範例 |
|
||
|------|:----:|------|------|
|
||
| `Name` | ✓ | 服務名稱 | `gateway` |
|
||
| `Host` | ✓ | 監聽位址 | `0.0.0.0` |
|
||
| `Port` | ✓ | HTTP 埠 | `8888` |
|
||
|
||
其餘 `RestConf` 欄位(`Timeout`、`Log`、`Prometheus` 等)可省略,使用 go-zero 預設。
|
||
|
||
---
|
||
|
||
## `Mongo`(`internal/library/mongo.Conf`)
|
||
|
||
**`Host` 留空或整段註解** → 不連 Mongo,`Notifier` / `MemberVerification` 不會注入(仍可跑 health API)。
|
||
|
||
| 欄位 | 必填 | 說明 | 本機 dev 建議 |
|
||
|------|:----:|------|----------------|
|
||
| `Schema` | 選 | 連線 scheme,預設 `mongodb` | `mongodb` |
|
||
| `Host` | 啟用時 ✓ | 主機;可含埠 `127.0.0.1:27017` | `127.0.0.1` |
|
||
| `Port` | 選 | `Host` 無埠時附加,**整數** | `27017` |
|
||
| `Database` | 啟用時 ✓ | 資料庫名 | `gateway`(與 docker init 一致) |
|
||
| `User` | 選 | 帳號 | 本機留空 |
|
||
| `Password` | 選 | 密碼 | 本機留空 |
|
||
| `AuthSource` | 選 | 驗證用 DB;帳號在 `admin` 建則填 `admin` | 本機留空 |
|
||
| `ReplicaName` | 選 | replica set 名稱 | 本機單機**留空** |
|
||
| `TLS` | 選 | 是否 `tls=true` | `false` |
|
||
| `MaxPoolSize` | 選 | 連線池上限 | `30` |
|
||
| `MinPoolSize` | 選 | 連線池下限 | `10` |
|
||
| `MaxConnIdleTime` | 選 | 閒置連線逾時 | `30m` |
|
||
| `Compressors` | 選 | 壓縮演算法陣列 | 省略(程式預設 zstd、snappy) |
|
||
| `ConnectTimeoutMs` | 選 | 啟動 Ping 逾時(毫秒) | 省略(預設 10s) |
|
||
|
||
**會建立的 collections**(自動,無需手動建表):`notifications`、`notification_dlq`。索引:`make mongo-index` 或 docker init。
|
||
|
||
**常見錯誤**
|
||
|
||
| 錯誤訊息 | 原因 |
|
||
|----------|------|
|
||
| `type mismatch for field "Mongo.Compressors"` | 曾用不存在的 `Port: "27017"` 或 `Compressors` 寫成單一字串 |
|
||
| `field "Mongo.xxx" is not set` | 舊版未加 `optional`;請更新程式或改用最精簡的 `gateway.dev.yaml` |
|
||
| `mongo: ping primary` 失敗 | 有填 `Mongo.Host` 但沒跑 `make deps-up` |
|
||
|
||
---
|
||
|
||
## `Redis`(go-zero `redis.RedisConf`)
|
||
|
||
**`Host` 留空**(`gateway.yaml` 預設)→ 不連 Redis。有 Mongo 時仍可用 memory 冪等/配額,但**無異步重試 worker**、**無 Member OTP**。
|
||
|
||
`gateway.yaml` 建議保留區塊並設空 Host:
|
||
|
||
```yaml
|
||
Redis:
|
||
Host: ""
|
||
Type: node
|
||
```
|
||
|
||
| 欄位 | 必填 | 說明 | 本機 dev 建議 |
|
||
|------|:----:|------|----------------|
|
||
| `Host` | 啟用時 ✓ | `host:port` | `localhost:6379` |
|
||
| `Type` | 啟用時 ✓ | 單機填 `node` | `node` |
|
||
| `Pass` | 選 | 密碼 | 省略 |
|
||
| `Tls` | 選 | TLS | 省略 |
|
||
|
||
---
|
||
|
||
## `Notification`(`internal/model/notification/config`)
|
||
|
||
僅在 **Mongo 已連線** 時由 `ServiceContext` 組裝 Notifier。子欄位皆可省略(有程式預設)。
|
||
|
||
### 根層
|
||
|
||
| 欄位 | 說明 | 預設 / 建議 |
|
||
|------|------|-------------|
|
||
| `DefaultLocale` | 模板語系 fallback | `zh-tw` |
|
||
| `RatePerTenant.Email` | 每租戶每日 Email 上限 | `100` |
|
||
| `RatePerTenant.SMS` | 每租戶每日 SMS 上限 | `50` |
|
||
|
||
### `Notification.Email`
|
||
|
||
| 欄位 | 說明 |
|
||
|------|------|
|
||
| `Provider` | 無真實 provider 時填 `mock` |
|
||
| `From` | 寄件者(Send 時帶入) |
|
||
| `APIKey` | 保留,目前未用 |
|
||
|
||
**SMTP**(`Enable: true` 時加入發信鏈,依 `Sort` failover):
|
||
|
||
| 欄位 | 說明 |
|
||
|------|------|
|
||
| `Enable` / `Sort` | 是否啟用、優先順序(數字小先試) |
|
||
| `Host` / `Port` | SMTP 主機與埠(MailHog:`localhost:1025`) |
|
||
| `Username` / `Password` | 認證 |
|
||
|
||
**SES**(AWS):
|
||
|
||
| 欄位 | 說明 |
|
||
|------|------|
|
||
| `Enable` / `Sort` | 同上 |
|
||
| `Region` / `AccessKey` / `SecretKey` / `SessionToken` | AWS 憑證 |
|
||
|
||
### `Notification.SMS`
|
||
|
||
| 欄位 | 說明 |
|
||
|------|------|
|
||
| `Provider` | 無真實 provider 時 `mock` |
|
||
| `Mitake.Enable` | 三竹簡訊 |
|
||
| `Mitake.User` / `Mitake.Password` | 三竹帳密 |
|
||
| `Mitake.Sort` | failover 順序 |
|
||
|
||
### `Notification.Async`
|
||
|
||
| 欄位 | 說明 |
|
||
|------|------|
|
||
| `QueueRedisKey` | Redis ZSET key(空則用內建 `notif:retry:zset`) |
|
||
| `Worker` | 背景重試 goroutine 數 |
|
||
| `MaxRetry` | 最大重試次數 |
|
||
| `BackoffSeconds` | 重試間隔(秒)陣列 |
|
||
|
||
需 **Mongo + Redis** 才會啟動 `RetryWorker`。
|
||
|
||
### `Notification.Push` / `Webhook`
|
||
|
||
保留欄位,目前未接線。
|
||
|
||
---
|
||
|
||
## `Member`(`internal/model/member/config`)
|
||
|
||
僅在 **Mongo + Redis + Notifier** 皆就緒時注入 `MemberVerification`。
|
||
|
||
### `Member.OTP`
|
||
|
||
| 欄位 | 說明 | 建議 |
|
||
|------|------|------|
|
||
| `Length` | OTP 位數 | `6` |
|
||
| `TTLSeconds` | challenge 存活秒數 | `300` |
|
||
| `MaxAttempts` | 驗證嘗試上限 | `5` |
|
||
| `ResendCooldownSeconds` | 重發冷卻 | `60` |
|
||
| `DailyVerifyLimit` | 每日驗證上限 | `10` |
|
||
|
||
---
|
||
|
||
## 功能與依賴對照
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph always [永遠可用]
|
||
H[health API]
|
||
end
|
||
subgraph mongo [Mongo.Host 有值]
|
||
N[Notifier Send/Get]
|
||
A[Admin DLQ]
|
||
end
|
||
subgraph redis [Redis.Host 有值]
|
||
Q[Enqueue + RetryWorker]
|
||
O[Member OTP]
|
||
end
|
||
H --> always
|
||
mongo --> N
|
||
mongo --> A
|
||
mongo --> redis
|
||
redis --> Q
|
||
redis --> O
|
||
```
|
||
|
||
| 你想用的功能 | Mongo | Redis |
|
||
|--------------|:-----:|:-----:|
|
||
| `/api/v1/health` | — | — |
|
||
| `Notifier.Send`(同步) | ✓ | 選(冪等/配額建議開) |
|
||
| `Notifier.Enqueue` + 重試 | ✓ | ✓ |
|
||
| Member 信箱/手機驗證 | ✓ | ✓ |
|
||
|
||
---
|
||
|
||
## 疑難排解
|
||
|
||
```bash
|
||
# 1. 只驗證 yaml 能否載入(不啟動服務)
|
||
go test ./internal/config/ -run TestLoadGatewayYAML -v
|
||
|
||
# 2. 看缺什麼欄位(啟動時)
|
||
go run gateway.go -f etc/gateway.yaml
|
||
|
||
# 3. dev 完整栈
|
||
make deps-up && make run-dev
|
||
curl -s http://127.0.0.1:8888/api/v1/health
|
||
```
|
||
|
||
若你改壞了 yaml,可從 repo 內的 `gateway.yaml` / `gateway.dev.yaml` 重新複製,再依本文件逐段打開需要的區塊。
|
||
|
||
---
|
||
|
||
## 相關文件
|
||
|
||
- [deploy/README.md](../deploy/README.md) — Docker Compose
|
||
- [internal/model/notification/README.md](../internal/model/notification/README.md) — 通知模組
|
||
- [internal/library/mongo/README.md](../internal/library/mongo/README.md) — Mongo 存取層
|