Skip to content

Commit d32fd21

Browse files
committed
feat: RCA
1 parent dcf155c commit d32fd21

4 files changed

Lines changed: 331 additions & 1 deletion

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import SeverityBadge from "@site/src/components/SeverityBadge";
1313
## 事件概述
1414

1515
**發生時間:** 2025/12/12 04:24:28 UTC+8
16-
**觸發事件** 地震後
16+
**觸發條件** 地震後
1717
**問題描述:** TREM Lite 出現偵測重複觸發的問題
1818
**根本原因:** upstream 資料不一致污染 cache,導致系統異常
1919

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

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
title: 2025/12/13 TREM Lite 地震報告重複推送問題
3+
authors: [yuyu1015]
4+
tags: [yuyu1015, rca]
5+
---
6+
7+
import SeverityBadge from "@site/src/components/SeverityBadge";
8+
import StatusBadge from "@site/src/components/StatusBadge";
9+
10+
<SeverityBadge level="medium" />
11+
<StatusBadge status="investigating" />
12+
13+
---
14+
15+
## 事件概述
16+
17+
**發生時間:** 2025/12/13 03:33 左右 UTC+8
18+
**觸發條件:** 維護過程中
19+
**問題描述:** TREM Lite 地震報告重複推送的問題
20+
**根本原因:** API 資料雜湊值不一致,導致地震報告重複推送
21+
22+
## 根本原因分析
23+
24+
### 問題根源
25+
26+
兩個不同來源的 API 資料雜湊值(md5)不一致,導致客戶端判斷為新的地震報告。
27+
28+
`api-1.exptech.dev`
29+
30+
```json
31+
[
32+
{
33+
"id": "114149-2025-1212-042428",
34+
"lat": 23.19,
35+
"lon": 120.47,
36+
"depth": 8.9,
37+
"loc": "臺南市政府東北方 36.4 公里 (位於臺南市楠西區)",
38+
"mag": 4,
39+
"time": 1765484668000,
40+
"int": 4,
41+
"trem": 1765484671592,
42+
"md5": "B00F1BCF25C80D8A4EAA865D1D8EEC33"
43+
},
44+
{
45+
"id": "114148-2025-1211-231940",
46+
"lat": 23.18,
47+
"lon": 120.66,
48+
"depth": 8.2,
49+
"loc": "高雄市政府北北東方 71.5 公里 (位於高雄市甲仙區)",
50+
"mag": 4.7,
51+
"time": 1765466380000,
52+
"int": 4,
53+
"trem": 1765466391158,
54+
"md5": "F2B6AE32A6E4D8A459ECEDFDE19180E6"
55+
},
56+
{
57+
"id": "114000-2025-1211-225941",
58+
"lat": 23.17,
59+
"lon": 120.67,
60+
"depth": 8,
61+
"loc": "高雄市政府北北東方 71.2 公里 (位於高雄市甲仙區)",
62+
"mag": 3.5,
63+
"time": 1765465181000,
64+
"int": 2,
65+
"trem": 1765465199063,
66+
"md5": "685F5C6EC26FBF1F9159906486A5C127"
67+
},
68+
{
69+
"id": "114147-2025-1211-224902",
70+
"lat": 23.18,
71+
"lon": 120.66,
72+
"depth": 8,
73+
"loc": "高雄市政府北北東方 71.1 公里 (位於高雄市甲仙區)",
74+
"mag": 4.7,
75+
"time": 1765464542000,
76+
"int": 4,
77+
"trem": 1765464552546,
78+
"md5": "F34095B26D0895AA0995F3028B76DE02"
79+
},
80+
{
81+
"id": "114000-2025-1211-124902",
82+
"lat": 24.62,
83+
"lon": 121.75,
84+
"depth": 45.4,
85+
"loc": "宜蘭縣政府南方 12.3 公里 (位於宜蘭縣冬山鄉)",
86+
"mag": 4,
87+
"time": 1765428542000,
88+
"int": 1,
89+
"trem": 1765428550547,
90+
"md5": "F1CC648A41D465CA2F60264ACCABC7A3"
91+
}
92+
]
93+
```
94+
95+
`api-2.exptech.dev`
96+
97+
```json
98+
[
99+
{
100+
"id": "114149-2025-1212-042428",
101+
"lat": 23.19,
102+
"lon": 120.47,
103+
"depth": 8.9,
104+
"loc": "臺南市政府東北方 36.4 公里 (位於臺南市楠西區)",
105+
"mag": 4,
106+
"time": 1765484668000,
107+
"int": 4,
108+
"trem": 1765484672700,
109+
"md5": "DA5510C9B54576B883E04F4DD7178E9C"
110+
},
111+
{
112+
"id": "114148-2025-1211-231940",
113+
"lat": 23.18,
114+
"lon": 120.66,
115+
"depth": 8.2,
116+
"loc": "高雄市政府北北東方 71.5 公里 (位於高雄市甲仙區)",
117+
"mag": 4.7,
118+
"time": 1765466380000,
119+
"int": 4,
120+
"trem": 1765466391208,
121+
"md5": "D207D655C1A9E720E7BBC33B1F4CCD33"
122+
},
123+
{
124+
"id": "114000-2025-1211-225941",
125+
"lat": 23.17,
126+
"lon": 120.67,
127+
"depth": 8,
128+
"loc": "高雄市政府北北東方 71.2 公里 (位於高雄市甲仙區)",
129+
"mag": 3.5,
130+
"time": 1765465181000,
131+
"int": 2,
132+
"trem": 1765465199151,
133+
"md5": "25A440BC96AC17E401AEFFFED42CD06C"
134+
},
135+
{
136+
"id": "114147-2025-1211-224902",
137+
"lat": 23.18,
138+
"lon": 120.66,
139+
"depth": 8,
140+
"loc": "高雄市政府北北東方 71.1 公里 (位於高雄市甲仙區)",
141+
"mag": 4.7,
142+
"time": 1765464542000,
143+
"int": 4,
144+
"trem": 1765464552550,
145+
"md5": "24C4744A01521C9540CE2D5FD209AF07"
146+
},
147+
{
148+
"id": "114000-2025-1211-124902",
149+
"lat": 24.62,
150+
"lon": 121.75,
151+
"depth": 45.4,
152+
"loc": "宜蘭縣政府南方 12.3 公里 (位於宜蘭縣冬山鄉)",
153+
"mag": 4,
154+
"time": 1765428542000,
155+
"int": 1,
156+
"trem": 0,
157+
"md5": "6C759AE5E57359B06662C6B0C31B68B1"
158+
}
159+
]
160+
```
161+
162+
### 問題說明
163+
164+
**問題主因:**
165+
166+
調查中
167+
168+
## 解決方案
169+
170+
### 改進說明
171+
172+
## 後續觀察
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { JSX } from "react";
2+
import styles from "./styles.module.css";
3+
4+
type StatusType = "investigating" | "resolved";
5+
6+
type StatusBadgeProps = {
7+
status: StatusType;
8+
title?: string;
9+
children?: string;
10+
}
11+
12+
const statusLabels: Record<StatusType, string> = {
13+
investigating: "調查中",
14+
resolved: "已結案"
15+
};
16+
17+
export default function StatusBadge({
18+
status,
19+
title = "狀態",
20+
children
21+
}: StatusBadgeProps): JSX.Element {
22+
const label = children || statusLabels[status];
23+
24+
return (
25+
<span className={`${styles.badge} ${styles[status]}`}>
26+
<span className={styles.indicator} />
27+
<span className={styles.title}>{title}</span>
28+
<span className={styles.divider} />
29+
<span className={styles.label}>{label}</span>
30+
</span>
31+
);
32+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/* 基礎樣式 - 毛玻璃效果 */
2+
.badge {
3+
display: inline-flex;
4+
align-items: center;
5+
gap: 8px;
6+
padding: 10px 16px;
7+
border-radius: 12px;
8+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
9+
color: white;
10+
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
11+
backdrop-filter: blur(20px) saturate(180%);
12+
-webkit-backdrop-filter: blur(20px) saturate(180%);
13+
background: rgba(30, 30, 30, 0.05);
14+
border: 2px solid rgba(255, 255, 255, 0.18);
15+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.15);
16+
}
17+
18+
[data-theme="light"] .badge {
19+
background: rgba(255, 255, 255, 0.1);
20+
color: #1a1a1a;
21+
text-shadow: none;
22+
border-color: rgba(0, 0, 0, 0.12);
23+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1), 0 2px 8px rgba(0, 0, 0, 0.08);
24+
}
25+
26+
/* 子元素樣式 */
27+
.indicator {
28+
width: 8px;
29+
height: 8px;
30+
border-radius: 50%;
31+
flex-shrink: 0;
32+
}
33+
34+
.title {
35+
font-size: 12px;
36+
font-weight: 500;
37+
opacity: 0.75;
38+
}
39+
40+
.divider {
41+
width: 1px;
42+
height: 14px;
43+
background: rgba(255, 255, 255, 0.25);
44+
}
45+
46+
[data-theme="light"] .divider {
47+
background: rgba(0, 0, 0, 0.15);
48+
}
49+
50+
.label {
51+
font-size: 15px;
52+
font-weight: 700;
53+
}
54+
55+
/* Investigating - 調查中 */
56+
.investigating {
57+
border-color: rgba(251, 191, 36, 0.5);
58+
background: rgba(251, 191, 36, 0.08);
59+
animation: glow-investigating 2s ease-in-out infinite;
60+
}
61+
62+
[data-theme="light"] .investigating {
63+
background: rgba(251, 191, 36, 0.06);
64+
}
65+
66+
.investigating .indicator {
67+
background: #fbbf24;
68+
box-shadow: 0 0 8px #fbbf24;
69+
animation: pulse-investigating 2s ease-in-out infinite;
70+
}
71+
72+
.investigating .label {
73+
color: #fcd34d;
74+
}
75+
76+
[data-theme="light"] .investigating .label {
77+
color: #d97706;
78+
}
79+
80+
@keyframes glow-investigating {
81+
0%,
82+
100% {
83+
box-shadow: 0 0 6px rgba(251, 191, 36, 0.3),
84+
0 0 12px rgba(251, 191, 36, 0.15);
85+
}
86+
50% {
87+
box-shadow: 0 0 12px rgba(251, 191, 36, 0.6),
88+
0 0 24px rgba(251, 191, 36, 0.4), 0 0 36px rgba(251, 191, 36, 0.2);
89+
}
90+
}
91+
92+
@keyframes pulse-investigating {
93+
0%,
94+
100% {
95+
opacity: 1;
96+
transform: scale(1);
97+
}
98+
50% {
99+
opacity: 0.7;
100+
transform: scale(1.1);
101+
}
102+
}
103+
104+
/* Resolved - 已結案 */
105+
.resolved {
106+
border-color: rgba(34, 197, 94, 0.5);
107+
background: rgba(34, 197, 94, 0.08);
108+
box-shadow: 0 0 8px rgba(34, 197, 94, 0.3);
109+
}
110+
111+
[data-theme="light"] .resolved {
112+
background: rgba(34, 197, 94, 0.06);
113+
}
114+
115+
.resolved .indicator {
116+
background: #22c55e;
117+
box-shadow: 0 0 8px #22c55e;
118+
}
119+
120+
.resolved .label {
121+
color: #4ade80;
122+
}
123+
124+
[data-theme="light"] .resolved .label {
125+
color: #16a34a;
126+
}

0 commit comments

Comments
 (0)