加入 Ollama GCP failover 診斷與 unhealthy skip
All checks were successful
CD Pipeline / deploy (push) Successful in 1m5s

This commit is contained in:
OoO
2026-05-25 14:16:51 +08:00
parent 44ef5a70a1
commit a00f34ce87
11 changed files with 341 additions and 8 deletions

View File

@@ -2,7 +2,7 @@
> **最後更新**: 2026-05-25 (台北時間)
> **狀態**: 🟢 四 AI Agent 自動化閉環已落地LLM 路由紅線升級為 Ollama-first 三主機級聯Gemini 備援預設關閉
> **適用版本**: V10.471
> **適用版本**: V10.473
---
@@ -26,6 +26,7 @@
- `allow_111_fallback=False` 且 GCP-A / GCP-B 皆失敗時,背景 embedding 會開啟短暫 GCP failure circuit預設 60 秒),期間不重複打兩台 GCP、不落 111避免 worker 與 log 被連續失敗拖慢GCP 恢復後會自然再試。
- 背景 embedding 的 GCP-only 熔斷屬於可降級背景能力,應記錄為明確 WARNING 與 circuit 狀態,不應每次污染 ERROR 通道;真正允許三主機 fallback 的同步 embedding 全失敗仍保留 ERROR。
- Scheduler host health probe 不只看 `/api/tags`GCP-A / GCP-B 節點必須再通過 `bge-m3` `/api/embed` 實作探針,才算 healthy。探針 timeout 預設 30s111 預設不納入這個背景 embedding 探針,避免監測任務把 fallback Mac 載入 `bge-m3`
- 背景 embedding 會讀取最近 `host_health_probes` runtime 結果;若 GCP-A / GCP-B 在 `OLLAMA_EMBED_HOST_HEALTH_SKIP_WINDOW_MINUTES=20` 視窗內已被標為 unhealthy`OllamaService.generate_embedding(..., allow_111_fallback=False)` 會先跳過該節點並開啟短暫 GCP circuit不再等待 30 秒 timeout也仍不落 111。此功能由 `OLLAMA_EMBED_HOST_HEALTH_SKIP_ENABLED=true` 控制DB 讀取失敗時 fail-open 回到原本網路 retry。
- BGE-M3 一致性檢查是監測任務,不是 fallback 壓測;預設只比對 GCP-A / GCP-B。111 Mac fallback 只有 `EMBED_CONSISTENCY_INCLUDE_111=true` 時才納入,避免每週背景檢查把 `bge-m3` 載入 111。
- OpenClaw Telegram Q&A 主路徑也不得綁單一 host`_call_qwen3_qa()` 必須透過 `OllamaService` 跑 GCP-A → GCP-B → 111並把實際落點寫入 `ai_calls.provider`
- OpenClaw Telegram 圖片商品辨識也必須 Ollama-first`_identify_product_name_with_ollama_vision()` 透過 `OllamaService` 嘗試 GCP-A → GCP-B → 111Gemini 只允許以 `openclaw_bot_image_gemini` caller 作為失敗後備援。

View File

@@ -122,3 +122,20 @@
- **原因**: Blackbox 或外部探測打 Dashboard 首頁 `/`,會觸發商品看板與 PChome 比價重型查詢;少量 sync worker 被長請求佔滿時,輕量 `/health` 也會排隊逾時。
- **檢查**: `docker logs momo-pro-system --since 20m | grep 'Blackbox-Exporter'` 應只看到 `GET /health``docker stats momo-db` 若接近多核心滿載,需同步看 `pg_stat_activity``latest_momo` 類查詢。
- **修復**: 188 的 `monitoring/prometheus.yml` 與 110 的 `/home/wooo/monitoring/prometheus.yml` blackbox HTTP targets 必須使用 `/health`Gunicorn 保持 `worker_class=gthread``GUNICORN_THREADS=4``preload_app=False`
### 12. GCP-A Ollama refused / 110:11435 502
- **快速診斷**: 在 repo 根目錄執行 `scripts/ops/diagnose_ollama_gcp_failover.sh`。此腳本不需要 root也不會修改 nginx、Docker、GCP 或正式服務。
- **判讀**:
- `GCP-A direct /api/version` 失敗且 `GCP-B direct` 成功primary VM、防火牆或 Ollama 服務異常;應用層會走 GCP-A → GCP-B → 111但仍需修 primary。
- `110 proxy primary` 502 且 `110 proxy secondary` 成功110 的 `11435` 固定代理 GCP-A所以 primary 掛時舊 proxy 入口會失敗;需 110 root 才能改 nginx 或 reload。
- `GCP-B embed` 成功但耗時接近 30s表示 `bge-m3` runner 慢但可用;若經常超過 30s應處理 GCP-B runner/CPU/模型併發,不要把 111 納入背景 embedding。
- **GCP-A 修復方向**:
- 有 GCP/SSH 權限時,先確認 VM 是否開機、Firewall 是否開 `22``11434`、Ollama process 是否在 listen。
- 110 現況若 `ssh gcp-a``port 22: Connection refused`,代表目前跳板無法進主機,不能靠 momo-pro app 修復。
- **110 proxy failover 方向**:
- 需要 root`sudo nginx -t`、修改 `/etc/nginx/sites-enabled/110-ollama-proxy.conf``sudo systemctl reload nginx`
- 若要讓 `11435` 在 GCP-A 掛時 fallback 到 GCP-B必須明確標註這是 proxy failover不代表 GCP-A 已恢復host health 仍應以 direct GCP-A 探針為準。
- **紅線**:
- 不要把背景 `bge-m3` 任務改落 111。
- 不要用更長 timeout 掩蓋 GCP-A refusedGCP-A 是 primary infra blocker。
- 沒有 110 root 或 GCP SSH 權限時,只能完成診斷、文件與應用層降級,不能假裝已修復 primary。

View File

@@ -54,6 +54,7 @@
- 2026-05-24 追記:同步 PChome 覆核頁 fast-count、輕量 render 與重算可採用指標後的 `routes/dashboard_routes.py` 行數;此處只更新 inventory不變更 dashboard 行為。
- 2026-05-24 追記:同步 PChome rescore audit 最新狀態口徑與單位價 multiplier 修正後的 `services/marketplace_product_matcher.py` 行數;此處只更新 inventory不變更拆分策略。
- 2026-05-24 追記:同步 PChome review queue 決策信封合併後的 `services/competitor_intel_repository.py` 行數;此處只更新 inventory不變更拆分策略。
- 2026-05-25 追記:同步背景 embedding 讀取 `host_health_probes` skip guard 後的 `services/ollama_service.py` 行數;此處只更新 inventory不變更 Ollama 路由決策。
## 達到或超過 800 行檔案清單
@@ -82,7 +83,7 @@
| 867 | `services/token_report_service.py` | P2 token report service | query / aggregation / chart payload / notification formatting |
| 3786 | `services/marketplace_product_matcher.py` | P2 marketplace matcher | identity parsing / unit-comparable scoring / search term quality / persistence normalization |
| 865 | `routes/daily_sales_routes.py` | P2 Daily Sales Blueprint | route glue / export helpers / daily query and formatting service |
| 1117 | `services/ollama_service.py` | P2 Ollama client | host health / request client / fallback policy / response parsing |
| 1266 | `services/ollama_service.py` | P2 Ollama client | host health / request client / fallback policy / response parsing |
| 849 | `services/pchome_crawler.py` | P2 PChome crawler | search fetch / parsing / fallback source handling / rate limit policy |
| 1100 | `services/code_review_pipeline_service.py` | P2 Code review pipeline service | scan orchestration / finding normalization / persistence adapter |
| 953 | `routes/export_routes.py` | P2 Export flow | export command/router glue / file path / download orchestration |

View File

@@ -25,6 +25,8 @@
- 2026-05-25 12:39 CST 狀態:已部署 `V10.469` 到 188正式 `/health``V10.469`。本輪 recreate `momo-app``scheduler``telegram-bot`;未使用 `--remove-orphans`,未碰 `momo-db`。Smoke 通過:三個 app 容器 healthy、首頁 / daily / growth / PChome review queue HTTP 200、Gemini hard disabled`allow_111_fallback=False` 時 GCP-only embedding 全失敗會開啟 failure circuit 並記 WARNING不再把預期內的背景熔斷打進 ERROR 通道。觀測到 GCP-B `/api/version` 200`/api/embed` 仍可能 15s timeout下一步需修 GCP-A primary 與 GCP-B runner/model 負載。
- 2026-05-25 12:53 CST 狀態:已部署 `V10.470` 到 188正式 `/health``V10.470`。本輪 recreate `momo-app``scheduler``telegram-bot`;未使用 `--remove-orphans`,未碰 `momo-db`。Smoke 通過:三容器 healthy、host health page HTTP 200 並顯示 Runtime 狀態、scheduler probe 寫入 DB。最新 `host_health_probes`GCP-A unhealthy11434 refused、GCP-B unhealthy`EmbedProbe ReadTimeout`, `/api/tags` 仍可列出 4 模型、111 healthy這補上「HTTP API 活著但模型 runtime 卡住」的假健康監控缺口。
- 2026-05-25 13:38 CST 狀態:已部署 `V10.471` 到 188正式 `/health``V10.471`。本輪 recreate `momo-app``scheduler``telegram-bot`;未使用 `--remove-orphans`,未碰 `momo-db`。Smoke 通過:三容器 healthy、首頁 / daily / growth / host_health / ppt_audit_history / PChome review queue HTTP 200。GCP-B `bge-m3` `/api/embed` 直接實測約 6.4s、7.3s、23.5s,原 `OLLAMA_EMBED_MAX_TIMEOUT=15` 與 host health `OLLAMA_HOST_HEALTH_EMBED_TIMEOUT=8` 會誤殺慢但成功的 embedding預設改為 30s。正式容器內 embedding smoke 回 1024 維、耗時 10.07s;手動 host health probe 後最新狀態為 GCP-A unhealthy、GCP-B healthy、111 healthy。背景 embedding 路由安全不變GCP-A → GCP-B不落 111。
- 2026-05-25 14:10 CST 起,`V10.472` 補 rootless GCP Ollama failover 診斷腳本與 DevOps SOP`scripts/ops/diagnose_ollama_gcp_failover.sh` 會檢查 direct GCP-A/GCP-B/111、110 proxy `11435/11436` 與 GCP-B `bge-m3` runtime。現況輸出GCP-A direct `/api/version` failed/refused、GCP-B direct OK、111 OK、110:11435 502、110:11436 OK、GCP-B embed OK110 無免密 sudo`ssh gcp-a` 22 refused、`ssh gcp-b` publickey denied因此 primary 修復需 GCP/SSH 或 110 root 權限。
- 2026-05-25 14:12 CST 起,`V10.473` 進行背景 embedding host_health skip`allow_111_fallback=false` 的背景 embedding 會讀最近 `host_health_probes`,若 GCP-A/GCP-B runtime 已被標 unhealthy直接跳過該節點並開 GCP circuit不等待 30 秒 timeout、不落 111DB 讀取失敗 fail-open。
- 2026-05-25 12:05 CST 狀態:`main` 已部署到 188正式 `/health``V10.467`,待推 Gitea。兩段變更已合併驗證V10.466 rescore duplicate 改看 latest-state7 筆 SKU 最新 attempt 全為 `rescore_accepted_current``competitor_prices` / `competitor_price_history` 目標計數未變V10.467 focused exact matcher 在容器內回 `exact / total_price / price_alert_exact`。本輪 recreate `momo-app``scheduler``telegram-bot`;未使用 `--remove-orphans`,未碰 `momo-db`。Smoke 通過:三容器 healthy、PChome rescore queue API HTTP 200、Gemini 24 小時無 provider 紀錄、Ollama env 順序維持 GCP-A → GCP-B → 111、3 分鐘三容器 log 未見 Traceback / ERROR / CRITICAL / IntegrityError。
## 1. MOMO / PChome 核心比價準確率
@@ -81,6 +83,7 @@
- 2026-05-25 12:27 CST 起,背景 embedding 在 GCP-A/GCP-B 全掛時開啟短暫 failure circuit這是降載保護不代表 primary 已恢復。部署 smoke 時 GCP-B `/api/version` 已恢復 200下一步仍需恢復 GCP-A Ollama 或更新 110 的可用 SSH/GCP 操作憑證。
- 2026-05-25 12:37 CST 起,背景 embedding GCP-only failure circuit 改用 WARNING 記錄,避免可預期降級污染 ERROR 告警通道。
- 2026-05-25 13:35 CST 起GCP-B `bge-m3` 實測 P95 波動已超過 15s背景 embedding / host health model probe timeout 預設改 30s若 30s 仍常 timeout需進一步處理 GCP-B runner/CPU/模型併發,而不是再把 111 納入背景任務。
- 2026-05-25 14:10 CST 起GCP-A refused 已明確歸類為 infra blocker應用層不得改成 111 背景 fallback也不得把 110:11435 502 當成 momo-app 故障。背景 embedding 可依 `host_health_probes` 跳過近期 unhealthy GCP host但查 DB 必須 fail-open。
## 4. 業績分析資料與圖表修復

View File

@@ -13,6 +13,8 @@
## 📅 詳細更新日誌 (考古存檔)
### 2026-05-24PChome 近門檻身份回收第二輪
- **V10.473 背景 embedding 讀取 host_health skip**: `OllamaService.generate_embedding(..., allow_111_fallback=False)` 會先查最近 `host_health_probes`;若 GCP-A/GCP-B 在 20 分鐘視窗內已由 runtime probe 標成 unhealthy背景 embedding 直接跳過該節點並開短暫 GCP circuit不等待 30 秒 timeout、不落 111。DB 讀取失敗時 fail-open 回原本 retry避免觀測層阻斷 embedding。
- **V10.472 GCP Ollama failover rootless 診斷**: 新增 `scripts/ops/diagnose_ollama_gcp_failover.sh` 與 DevOps SOP可不需 root 檢查 GCP-A/GCP-B/111 direct、110 proxy `11435/11436` 與 GCP-B `bge-m3` runtime。現況確認GCP-A `22/11434` refused、GCP-B `22/11434` open 但 SSH key denied、GCP-B embed OK、110:11435 502、110:11436 OKprimary 修復需 GCP/SSH 或 110 root 權限。
- **V10.471 GCP-B embedding timeout 校準**: GCP-B `bge-m3` `/api/embed` 直接實測約 6.4s / 7.3s / 23.5s,原 `OLLAMA_EMBED_MAX_TIMEOUT=15` 與 host health `OLLAMA_HOST_HEALTH_EMBED_TIMEOUT=8` 會誤判慢但成功的 embedding預設改為 30s。背景 embedding 仍只跑 GCP-A/GCP-B不落 111。
- **V10.470 Ollama host health 實作探針**: `run_host_health_probe()` 對 GCP-A / GCP-B 在 `/api/tags` 成功後追加短 `bge-m3` `/api/embed` probe避免 GCP-B 出現 tags/version 正常、但實際 embedding runner 20s timeout 時仍被標 healthy111 預設不做背景 embedding probe避免監測任務把 fallback Mac 載入 `bge-m3`
- **V10.469 Background embedding 降級語意修正**: `OllamaService.generate_embedding(..., allow_111_fallback=False)` 在 GCP-A/GCP-B 全失敗時會開啟短暫 failure circuit 並記 WARNING不再把背景 `bge-m3` 降級熔斷每分鐘寫成 ERROR同步或允許三主機 fallback 的 embedding 全失敗仍維持 ERROR保留真正阻塞型故障訊號。