跳至主要内容

[RCA] 12/13 TREM 地震報告重複推送問題

· 閱讀時間約 3 分鐘
YuYu1015
Full-Stack Engineer (全端工程師)
嚴重程度 狀態已結案

事件概述

  • 發生時間: 2025/12/13 03:33 (UTC+8) 左右
  • 觸發條件: 維護過程中
  • 問題描述: TREM Lite 地震報告重複推送的問題
  • 根本原因: 快取鍵衝突

時間軸

時間 (UTC+8)事件
2025/12/13 03:33問題發生:TREM Lite 地震報告重複推送
2025/12/13 03:53確認問題並開始進行修復
2025/12/13 03:54執行緊急處理,嘗試緩解問題
2025/12/13 03:55觀察到問題已緩解

事件經過

在進行 TNN Core Server 的維護作業期間,調整 Nginx 設定時將 report server 容器重啟,隨後發生 TREM Lite 地震報告重複推送的問題。 問題發生後,立即進行排查,確認問題根源並執行修復,約 22 分鐘後問題得到緩解。

根本原因分析

問題根源

快取鍵設定不當,導致不同參數的請求共用相同的快取結果,造成 API 回應不符合預期。

問題說明

問題主因:

當系統從不同的 upstream 取得資料時,會將不一致的資料寫入 cache。

故障時 Nginx 設定如下:

location ~ ^/api/(v1|v2)/eq/report {
set $cache_key "$uri|$arg_limit|$arg_page|$arg_minIntensity|$arg_maxIntensity|$arg_minMagnitude|$arg_maxMagnitude|$arg_minDepth|$arg_maxDepth";
proxy_pass http://report;
proxy_cache_key $cache_key;
include /etc/nginx/conf.d/cache_1s.inc;
}

cache_1s.inc

proxy_cache my_cache;
proxy_cache_key $url;
proxy_cache_valid 200 1s;
proxy_cache_lock on;
proxy_cache_lock_timeout 1s;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
proxy_cache_background_update on;

問題點:

  1. 快取鍵設定衝突:

    • location 區塊中設定了 proxy_cache_key $cache_key(使用自訂的快取鍵)
    • 但在 cache_1s.inc 中又設定了 proxy_cache_key $url(使用 URL 作為快取鍵)
    • 兩個 proxy_cache_key 設定衝突,導致快取鍵不一致
  2. 回應不符預期:

    • cache_1s.inc 中的 proxy_cache_key $url; 會覆蓋 location 區塊中的 proxy_cache_key $cache_key;
    • 當請求有查詢參數和沒有查詢參數時,$url 可能產生相同的快取鍵
    • 例如:/api/v1/eq/report/api/v1/eq/report?limit=10 可能使用相同的快取鍵
    • 導致不同參數的請求共用相同的快取結果,返回不符合預期的資料
  3. 影響:

    • 客戶端收到不一致的地震報告資料
    • 相同的地震事件被重複推送

解決方案

修改後的設定

移除 cache_1s.inc 中的 proxy_cache_key $url; 設定,統一使用 location 區塊中定義的 $cache_key

location ~ ^/api/(v1|v2)/eq/report {
set $cache_key "$uri|$arg_limit|$arg_page|$arg_minIntensity|$arg_maxIntensity|$arg_minMagnitude|$arg_maxMagnitude|$arg_minDepth|$arg_maxDepth";
proxy_pass http://report;
proxy_cache_key $cache_key;
include /etc/nginx/conf.d/cache_1s.inc;
}

cache_1s.inc(修改後)

proxy_cache my_cache;
# 移除 proxy_cache_key $url; 避免與 location 區塊中的設定衝突
proxy_cache_valid 200 1s;
proxy_cache_lock on;
proxy_cache_lock_timeout 1s;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
proxy_cache_background_update on;

改進說明

  1. 統一快取鍵設定: 移除 cache_1s.inc 中的 proxy_cache_key $url;,避免與 location 區塊中的自訂快取鍵衝突

  2. 確保快取鍵唯一性: 使用包含所有查詢參數的自訂快取鍵,確保有參數和無參數的請求使用不同的快取鍵

  3. 確保回應正確性: 透過正確的快取鍵設定,確保不同參數的請求使用不同的快取,返回符合預期的資料

後續觀察

經觀察後,問題已得到緩解。