Skip to content

Commit 77f69e8

Browse files
committed
fix: RCA (2025-12-13_1)
1 parent e5e5a85 commit 77f69e8

2 files changed

Lines changed: 73 additions & 162 deletions

File tree

blog/RCA/2025-12-13_1.mdx

Lines changed: 73 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import StatusBadge from "@site/src/components/StatusBadge";
99
import ImageLightbox from "@site/src/components/ImageLightbox";
1010

1111
<SeverityBadge level="medium" />
12-
<StatusBadge status="investigating" />
12+
<StatusBadge status="resolved" />
1313

1414
---
1515

@@ -18,7 +18,7 @@ import ImageLightbox from "@site/src/components/ImageLightbox";
1818
- **發生時間:** 2025/12/13 03:33 (UTC+8) 左右
1919
- **觸發條件:** 維護過程中
2020
- **問題描述:** TREM Lite 地震報告重複推送的問題
21-
- **根本原因:** API 資料雜湊值不一致,導致地震報告重複推送
21+
- **根本原因:** 快取鍵衝突
2222

2323
## 時間軸
2424

@@ -38,180 +38,91 @@ import ImageLightbox from "@site/src/components/ImageLightbox";
3838

3939
### 問題根源
4040

41-
兩個不同來源的 API 伺服器(`api-1.exptech.dev``api-2.exptech.dev`)對於相同的地震事件,產生的 MD5 雜湊值不一致,導致客戶端判斷為新的地震報告,進而產生重複推送的問題。
42-
43-
**關鍵差異:**
44-
45-
從上述 API 回應資料可以觀察到,相同的地震事件(相同的 `id`)在兩個 API 伺服器上:
46-
47-
- `trem` 時間戳不同(例如:`1765484671592` vs `1765484672700`
48-
- 因此計算出的 `md5` 雜湊值也不同(例如:`B00F1BCF25C80D8A4EAA865D1D8EEC33` vs `DA5510C9B54576B883E04F4DD7178E9C`
49-
50-
`api-1.exptech.dev`
51-
52-
```json
53-
[
54-
{
55-
"id": "114149-2025-1212-042428",
56-
"lat": 23.19,
57-
"lon": 120.47,
58-
"depth": 8.9,
59-
"loc": "臺南市政府東北方 36.4 公里 (位於臺南市楠西區)",
60-
"mag": 4,
61-
"time": 1765484668000,
62-
"int": 4,
63-
"trem": 1765484671592,
64-
"md5": "B00F1BCF25C80D8A4EAA865D1D8EEC33"
65-
},
66-
{
67-
"id": "114148-2025-1211-231940",
68-
"lat": 23.18,
69-
"lon": 120.66,
70-
"depth": 8.2,
71-
"loc": "高雄市政府北北東方 71.5 公里 (位於高雄市甲仙區)",
72-
"mag": 4.7,
73-
"time": 1765466380000,
74-
"int": 4,
75-
"trem": 1765466391158,
76-
"md5": "F2B6AE32A6E4D8A459ECEDFDE19180E6"
77-
},
78-
{
79-
"id": "114000-2025-1211-225941",
80-
"lat": 23.17,
81-
"lon": 120.67,
82-
"depth": 8,
83-
"loc": "高雄市政府北北東方 71.2 公里 (位於高雄市甲仙區)",
84-
"mag": 3.5,
85-
"time": 1765465181000,
86-
"int": 2,
87-
"trem": 1765465199063,
88-
"md5": "685F5C6EC26FBF1F9159906486A5C127"
89-
},
90-
{
91-
"id": "114147-2025-1211-224902",
92-
"lat": 23.18,
93-
"lon": 120.66,
94-
"depth": 8,
95-
"loc": "高雄市政府北北東方 71.1 公里 (位於高雄市甲仙區)",
96-
"mag": 4.7,
97-
"time": 1765464542000,
98-
"int": 4,
99-
"trem": 1765464552546,
100-
"md5": "F34095B26D0895AA0995F3028B76DE02"
101-
},
102-
{
103-
"id": "114000-2025-1211-124902",
104-
"lat": 24.62,
105-
"lon": 121.75,
106-
"depth": 45.4,
107-
"loc": "宜蘭縣政府南方 12.3 公里 (位於宜蘭縣冬山鄉)",
108-
"mag": 4,
109-
"time": 1765428542000,
110-
"int": 1,
111-
"trem": 1765428550547,
112-
"md5": "F1CC648A41D465CA2F60264ACCABC7A3"
113-
}
114-
]
41+
快取鍵設定不當,導致不同參數的請求共用相同的快取結果,造成 API 回應不符合預期。
42+
43+
### 問題說明
44+
45+
**問題主因:**
46+
47+
當系統從不同的 upstream 取得資料時,會將不一致的資料寫入 cache。
48+
49+
故障時 Nginx 設定如下:
50+
51+
```bash
52+
location ~ ^/api/(v1|v2)/eq/report {
53+
set $cache_key "$uri|$arg_limit|$arg_page|$arg_minIntensity|$arg_maxIntensity|$arg_minMagnitude|$arg_maxMagnitude|$arg_minDepth|$arg_maxDepth";
54+
proxy_pass http://report;
55+
proxy_cache_key $cache_key;
56+
include /etc/nginx/conf.d/cache_1s.inc;
57+
}
11558
```
11659

117-
`api-2.exptech.dev`
118-
119-
```json
120-
[
121-
{
122-
"id": "114149-2025-1212-042428",
123-
"lat": 23.19,
124-
"lon": 120.47,
125-
"depth": 8.9,
126-
"loc": "臺南市政府東北方 36.4 公里 (位於臺南市楠西區)",
127-
"mag": 4,
128-
"time": 1765484668000,
129-
"int": 4,
130-
"trem": 1765484672700,
131-
"md5": "DA5510C9B54576B883E04F4DD7178E9C"
132-
},
133-
{
134-
"id": "114148-2025-1211-231940",
135-
"lat": 23.18,
136-
"lon": 120.66,
137-
"depth": 8.2,
138-
"loc": "高雄市政府北北東方 71.5 公里 (位於高雄市甲仙區)",
139-
"mag": 4.7,
140-
"time": 1765466380000,
141-
"int": 4,
142-
"trem": 1765466391208,
143-
"md5": "D207D655C1A9E720E7BBC33B1F4CCD33"
144-
},
145-
{
146-
"id": "114000-2025-1211-225941",
147-
"lat": 23.17,
148-
"lon": 120.67,
149-
"depth": 8,
150-
"loc": "高雄市政府北北東方 71.2 公里 (位於高雄市甲仙區)",
151-
"mag": 3.5,
152-
"time": 1765465181000,
153-
"int": 2,
154-
"trem": 1765465199151,
155-
"md5": "25A440BC96AC17E401AEFFFED42CD06C"
156-
},
157-
{
158-
"id": "114147-2025-1211-224902",
159-
"lat": 23.18,
160-
"lon": 120.66,
161-
"depth": 8,
162-
"loc": "高雄市政府北北東方 71.1 公里 (位於高雄市甲仙區)",
163-
"mag": 4.7,
164-
"time": 1765464542000,
165-
"int": 4,
166-
"trem": 1765464552550,
167-
"md5": "24C4744A01521C9540CE2D5FD209AF07"
168-
},
169-
{
170-
"id": "114000-2025-1211-124902",
171-
"lat": 24.62,
172-
"lon": 121.75,
173-
"depth": 45.4,
174-
"loc": "宜蘭縣政府南方 12.3 公里 (位於宜蘭縣冬山鄉)",
175-
"mag": 4,
176-
"time": 1765428542000,
177-
"int": 1,
178-
"trem": 0,
179-
"md5": "6C759AE5E57359B06662C6B0C31B68B1"
180-
}
181-
]
60+
`cache_1s.inc`
61+
62+
```bash
63+
proxy_cache my_cache;
64+
proxy_cache_key $url;
65+
proxy_cache_valid 200 1s;
66+
proxy_cache_lock on;
67+
proxy_cache_lock_timeout 1s;
68+
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
69+
proxy_cache_background_update on;
18270
```
18371

184-
### 問題說明
72+
**問題點:**
18573

186-
**問題主因**
74+
1. **快取鍵設定衝突**
18775

188-
可以從下方圖片發現,兩邊 (`TNN``TPE`) 的 **ID** 不一致。
76+
-`location` 區塊中設定了 `proxy_cache_key $cache_key`(使用自訂的快取鍵)
77+
- 但在 `cache_1s.inc` 中又設定了 `proxy_cache_key $url`(使用 URL 作為快取鍵)
78+
- 兩個 `proxy_cache_key` 設定衝突,導致快取鍵不一致
18979

190-
<ImageLightbox src="/img/RCA/2025-12-13_1/image.png" alt="問題說明圖" />
80+
2. **回應不符預期:**
19181

192-
伺服器上的 **MD5 雜湊值** 計算方式如下:
82+
- `cache_1s.inc` 中的 `proxy_cache_key $url;` 會覆蓋 `location` 區塊中的 `proxy_cache_key $cache_key;`
83+
- 當請求有查詢參數和沒有查詢參數時,`$url` 可能產生相同的快取鍵
84+
- 例如:`/api/v1/eq/report``/api/v1/eq/report?limit=10` 可能使用相同的快取鍵
85+
- 導致不同參數的請求共用相同的快取結果,返回不符合預期的資料
19386

194-
```js
195-
const ans = {
196-
...earthquakeData, // CWA 地震報告
197-
trem, // TREM EQ ID
198-
md5: calculateMD5Hash(
199-
JSON.stringify({
200-
...earthquakeData,
201-
trem,
202-
})
203-
).toLocaleUpperCase(), // MD5 雜湊值
204-
};
87+
3. **影響:**
88+
- 客戶端收到不一致的地震報告資料
89+
- 相同的地震事件被重複推送
90+
91+
## 解決方案
92+
93+
### 修改後的設定
94+
95+
移除 `cache_1s.inc` 中的 `proxy_cache_key $url;` 設定,統一使用 `location` 區塊中定義的 `$cache_key`
96+
97+
```bash
98+
location ~ ^/api/(v1|v2)/eq/report {
99+
set $cache_key "$uri|$arg_limit|$arg_page|$arg_minIntensity|$arg_maxIntensity|$arg_minMagnitude|$arg_maxMagnitude|$arg_minDepth|$arg_maxDepth";
100+
proxy_pass http://report;
101+
proxy_cache_key $cache_key;
102+
include /etc/nginx/conf.d/cache_1s.inc;
103+
}
205104
```
206105

207-
**TREM EQ ID** 的取得方式如下:
106+
`cache_1s.inc`(修改後)
208107

209-
```sql
210-
SELECT ID FROM trem_report WHERE Cwa_id = ? LIMIT 1;
108+
```bash
109+
proxy_cache my_cache;
110+
# 移除 proxy_cache_key $url; 避免與 location 區塊中的設定衝突
111+
proxy_cache_valid 200 1s;
112+
proxy_cache_lock on;
113+
proxy_cache_lock_timeout 1s;
114+
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
115+
proxy_cache_background_update on;
211116
```
212117

213-
綜上所述,**MD5 雜湊值** 的不一致最終導致問題的發生。
118+
### 改進說明
214119

215-
## 解決方案
120+
1. **統一快取鍵設定:** 移除 `cache_1s.inc` 中的 `proxy_cache_key $url;`,避免與 `location` 區塊中的自訂快取鍵衝突
121+
122+
2. **確保快取鍵唯一性:** 使用包含所有查詢參數的自訂快取鍵,確保有參數和無參數的請求使用不同的快取鍵
123+
124+
3. **確保回應正確性:** 透過正確的快取鍵設定,確保不同參數的請求使用不同的快取,返回符合預期的資料
216125

217126
## 後續觀察
127+
128+
經觀察後,問題已得到緩解。
-184 KB
Binary file not shown.

0 commit comments

Comments
 (0)