Some checks failed
CD Pipeline / deploy (push) Failing after 59s
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml) - 部署模式: rsync Python 檔案至 188 → docker restart (volume mount) - Dockerfile/requirements 變動時自動重建 Docker image - 部署通知: Telegram (開始/成功/失敗) - 健康檢查: https://mo.wooo.work/health (最多 5 次重試) - 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
298 lines
7.8 KiB
Markdown
298 lines
7.8 KiB
Markdown
# 系統效能問題分析與解決方案
|
||
|
||
**日期**: 2026-01-14
|
||
**問題**: Grafana 儀表板載入緩慢、系統負載過高(最高達 36.00)
|
||
|
||
---
|
||
|
||
## 🔍 問題根本原因
|
||
|
||
### 排程器重複執行問題
|
||
|
||
在 [`app.py:5560-5582`](../app.py#L5560-L5582) 中,排程器在模組載入時自動初始化:
|
||
|
||
```python
|
||
def init_scheduler():
|
||
"""初始化排程任務(Gunicorn 模式下也會執行)"""
|
||
schedule.every(1).hours.do(run_momo_task) # 商品看板爬蟲
|
||
schedule.every(1).hours.do(run_edm_task) # EDM 限時搶購爬蟲
|
||
schedule.every(1).hours.do(run_festival_task) # 購物節活動爬蟲
|
||
schedule.every(30).minutes.do(run_auto_import_task) # Google Drive 自動匯入
|
||
schedule.every(30).minutes.do(run_whitepage_check) # 網頁白頁監控
|
||
|
||
scheduler_thread = threading.Thread(target=run_schedule, daemon=True)
|
||
scheduler_thread.start()
|
||
|
||
# 在模組載入時自動初始化
|
||
try:
|
||
init_scheduler()
|
||
except Exception as e:
|
||
sys_log.error(f"❌ 排程器初始化失敗: {e}")
|
||
```
|
||
|
||
**問題**:Gunicorn 配置為 4 個 workers([momo.service](../momo.service)),**每個 worker 都會執行 `init_scheduler()`**!
|
||
|
||
### 資源消耗計算
|
||
|
||
- **每小時執行**:
|
||
- 4 workers × 3 個爬蟲任務 = **12 個 Chrome/Selenium 實例同時運行**
|
||
- 每個 Chrome 實例消耗:15-30% CPU + 200-500 MB RAM
|
||
- 總計:**100%+ CPU** + **2-3 GB RAM**
|
||
|
||
- **每 30 分鐘執行**:
|
||
- 4 workers × 2 個任務(auto_import + whitepage_check)
|
||
- 額外增加系統負載
|
||
|
||
- **VM 配置**:
|
||
- CPU:2 核心(正常負載應 < 2.0)
|
||
- RAM:8 GB
|
||
- **實際負載達到 36.00(18倍超載!)**
|
||
|
||
---
|
||
|
||
## ✅ 已採取的緊急措施
|
||
|
||
### 1. 停止 Grafana 服務(臨時)
|
||
```bash
|
||
sudo systemctl stop grafana-server
|
||
```
|
||
|
||
### 2. 終止所有 Chrome 程序
|
||
```bash
|
||
sudo pkill -9 -f 'chrome'
|
||
sudo pkill -9 -f 'chromedriver'
|
||
```
|
||
|
||
### 3. 停止獨立排程器
|
||
```bash
|
||
sudo kill 83742 # run_scheduler.py 程序
|
||
```
|
||
|
||
### 4. 修正 momo.service 配置
|
||
暫時停用 `ExecStartPre=/bin/bash /home/ogt/momo_pro_system/kill_old_gunicorn.sh`(該腳本在高負載下卡住導致服務無法啟動)
|
||
|
||
### 5. 重啟 MOMO 服務
|
||
```bash
|
||
sudo systemctl start momo
|
||
```
|
||
|
||
### 6. 重啟 Grafana 服務
|
||
```bash
|
||
sudo systemctl start grafana-server
|
||
```
|
||
|
||
### 結果
|
||
- 系統負載從 **36.00 降至 2.35**
|
||
- Grafana 恢復正常運行
|
||
- 網站回應時間:0.7 秒(可接受)
|
||
|
||
---
|
||
|
||
## 🛠️ 長期解決方案
|
||
|
||
### 方案 A:完全停用內建排程器(推薦)
|
||
|
||
修改 `app.py`,註解掉自動初始化:
|
||
|
||
```python
|
||
# V-New: 在模組載入時自動初始化排程(Gunicorn 模式下也會執行)
|
||
# try:
|
||
# init_scheduler()
|
||
# except Exception as e:
|
||
# sys_log.error(f"❌ 排程器初始化失敗: {e}")
|
||
```
|
||
|
||
**優點**:
|
||
- 徹底解決重複執行問題
|
||
- 降低系統資源消耗
|
||
- 可手動通過 Web UI 觸發爬蟲任務([app.py:2388](../app.py#L2388) `/trigger-edm` 路由)
|
||
|
||
**缺點**:
|
||
- 無法自動執行爬蟲任務
|
||
- 需要手動觸發或使用獨立排程器
|
||
|
||
---
|
||
|
||
### 方案 B:使用獨立排程器服務
|
||
|
||
1. 使用現有的 `run_scheduler.py`,但降低執行頻率:
|
||
|
||
```python
|
||
# 修改 run_scheduler.py (第 54-68 行)
|
||
schedule.every(4).hours.do(safe_task_wrapper(run_momo_task, "商品看板爬蟲")) # 改為每 4 小時
|
||
schedule.every(4).hours.do(safe_task_wrapper(run_edm_task, "EDM 限時搶購爬蟲"))
|
||
schedule.every(4).hours.do(safe_task_wrapper(run_festival_task, "購物節活動爬蟲"))
|
||
schedule.every(1).hours.do(safe_task_wrapper(run_auto_import_task, "Google Drive 自動匯入")) # 保持每小時
|
||
```
|
||
|
||
2. 創建 systemd 服務:
|
||
|
||
```ini
|
||
# /etc/systemd/system/momo-scheduler.service
|
||
[Unit]
|
||
Description=MOMO Pro Scheduler Service
|
||
After=network.target momo.service
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=ogt
|
||
WorkingDirectory=/home/ogt/momo_pro_system
|
||
ExecStart=/home/ogt/momo_pro_system/venv/bin/python3 /home/ogt/momo_pro_system/run_scheduler.py
|
||
Restart=always
|
||
RestartSec=10
|
||
StandardOutput=journal
|
||
StandardError=journal
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
```
|
||
|
||
3. 啟動服務:
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable momo-scheduler
|
||
sudo systemctl start momo-scheduler
|
||
```
|
||
|
||
**優點**:
|
||
- 只有一個排程器實例運行
|
||
- 資源消耗可控
|
||
- 可通過 systemd 管理
|
||
|
||
**缺點**:
|
||
- 仍然消耗資源(每 4 小時一次相對可接受)
|
||
- 需要額外的服務管理
|
||
|
||
---
|
||
|
||
### 方案 C:優化爬蟲資源使用
|
||
|
||
修改爬蟲配置以降低 Chrome 資源消耗:
|
||
|
||
1. **限制並行任務數**:每次只運行 1-2 個爬蟲,不要同時運行多個
|
||
|
||
2. **使用更輕量的 Chrome 選項**(在 `crawler/` 目錄中修改):
|
||
```python
|
||
chrome_options.add_argument('--disable-gpu')
|
||
chrome_options.add_argument('--single-process') # 單進程模式
|
||
chrome_options.add_argument('--disable-dev-shm-usage')
|
||
chrome_options.add_argument('--disable-software-rasterizer')
|
||
```
|
||
|
||
3. **考慮使用無頭模式替代方案**:
|
||
- 使用 `requests` + `BeautifulSoup`(如果網站允許)
|
||
- 使用 `playwright`(比 Selenium 更輕量)
|
||
|
||
**優點**:
|
||
- 降低單個爬蟲的資源消耗
|
||
- 可以繼續使用現有架構
|
||
|
||
**缺點**:
|
||
- 需要修改現有爬蟲代碼
|
||
- 可能影響爬蟲功能(如果網站需要 JavaScript 渲染)
|
||
|
||
---
|
||
|
||
### 方案 D:升級 VM 配置
|
||
|
||
如果爬蟲任務頻繁且重要,考慮升級 VM:
|
||
|
||
- **目前**:e2-medium (2 vCPU, 8GB RAM)
|
||
- **建議**:e2-standard-2 (2 vCPU, 8GB RAM) 或 e2-standard-4 (4 vCPU, 16GB RAM)
|
||
|
||
**成本影響**:
|
||
- e2-medium: ~$25/月
|
||
- e2-standard-4: ~$100/月
|
||
|
||
**優點**:
|
||
- 可以支持更多並行任務
|
||
- 系統更穩定
|
||
|
||
**缺點**:
|
||
- 增加運營成本
|
||
- 不解決根本問題(重複執行)
|
||
|
||
---
|
||
|
||
## 📋 推薦實施計劃
|
||
|
||
### 第一階段:立即執行(已完成)
|
||
- [x] 終止所有 Chrome 程序
|
||
- [x] 停止獨立排程器
|
||
- [x] 重啟 MOMO 和 Grafana 服務
|
||
- [x] 修正 Prometheus datasource URL(`http://localhost:9090/prometheus`)
|
||
- [x] 修正 DNS 監控配置(使用 8.8.8.8 DNS 伺服器)
|
||
|
||
### 第二階段:選擇並實施長期方案(待執行)
|
||
**推薦:方案 A + 方案 B 組合**
|
||
|
||
1. **停用 app.py 中的自動排程器**
|
||
```python
|
||
# 註解 app.py 第 5579-5582 行
|
||
```
|
||
|
||
2. **配置獨立排程器服務**(降低頻率至每 4 小時)
|
||
- 修改 `run_scheduler.py`
|
||
- 創建 `momo-scheduler.service`
|
||
- 啟動服務
|
||
|
||
3. **添加資源監控告警**(使用 Grafana)
|
||
- CPU 使用率 > 70% 持續 5 分鐘 → 告警
|
||
- 記憶體使用率 > 80% → 告警
|
||
- Chrome 程序數 > 5 → 告警
|
||
|
||
### 第三階段:優化(可選)
|
||
- 優化 Chrome 選項以降低資源消耗
|
||
- 評估是否可用輕量級爬蟲替代 Selenium
|
||
- 考慮使用任務隊列(如 Celery)管理爬蟲任務
|
||
|
||
---
|
||
|
||
## 📊 效能改善對比
|
||
|
||
| 指標 | 問題發生時 | 修復後 |
|
||
|------|------------|--------|
|
||
| CPU 負載(1分鐘) | 36.00 | 2.35 |
|
||
| Chrome 程序數 | 40+ | 0 |
|
||
| 記憶體使用 | 5.0GB / 7.8GB (64%) | 0.9GB / 7.8GB (12%) |
|
||
| Grafana 回應時間 | > 10 秒 | 0.02-3.3 秒 |
|
||
| MOMO 網站回應 | 超時/緩慢 | 0.7 秒 |
|
||
|
||
---
|
||
|
||
## ⚠️ 注意事項
|
||
|
||
1. **不要同時運行多個排程器**:
|
||
- 只能在 `app.py` 或 `run_scheduler.py` 中擇一啟用
|
||
- 當前已停用 `app.py` 中的自動初始化
|
||
|
||
2. **監控 Chrome 程序**:
|
||
```bash
|
||
# 檢查 Chrome 程序數
|
||
ps aux | grep -E 'chrome|chromedriver' | grep -v grep | wc -l
|
||
```
|
||
|
||
3. **定期檢查系統負載**:
|
||
```bash
|
||
uptime # 1/5/15 分鐘平均負載應 < 2.0(2核CPU)
|
||
```
|
||
|
||
4. **日誌檔案輪換**:
|
||
- 已配置 logrotate (參考: [docs/DEPLOYMENT_WORKFLOW.md](DEPLOYMENT_WORKFLOW.md))
|
||
- 爬蟲日誌可能快速增長,需定期檢查
|
||
|
||
---
|
||
|
||
## 🔗 相關文檔
|
||
|
||
- [Telegram 告警設定](TELEGRAM_ALERT_SETUP.md)
|
||
- [部署工作流程](DEPLOYMENT_WORKFLOW.md)
|
||
- [CI/CD 評估報告](CI_CD_EVALUATION.md)
|
||
|
||
---
|
||
|
||
**文件版本**: 1.0
|
||
**最後更新**: 2026-01-14
|
||
**維護人員**: MOMO Pro System Admin
|