架構與異地備援
ExpTech 的地震即時資料採異地備援:臺南(臺灣)與東京(日本)兩座核心節點同時接收每一台測站的資料,各自完成即時運算,並在兩地之間同步、去重。任一座核心節點停擺,另一座照常產出即時震度與波形。中繼資料庫在兩地之間同步複寫,由臺南、東京、臺北三地的多數決共識自動故障轉移;即時串流則由臺北、高雄兩個負載平衡入口對外提供。
測站雙上行50 Hz 三軸加速度,在測站端計算震度,每 500 ms 送出
主鏈路臺南UDP · WebSocket 備援備援鏈路東京UDP · WebSocket 備援
臺南核心節點
接收測站資料驗證簽章、防重放
即時震度 RTS
即時波形
時序資料庫震波與震度,保留 7 天ClickHouse
中繼資料庫寫入只導向目前的主庫PostgreSQLHAProxy
東京核心節點
接收測站資料驗證簽章、防重放
即時震度 RTS
即時波形
時序資料庫震波與震度,保留 7 天ClickHouse
中繼資料庫寫入只導向目前的主庫PostgreSQLHAProxy
訊息叢集跨站同步 · 去重
同步串流複寫主庫失效時自動提升備庫Patroni
三地多數決共識etcd臺南東京臺北負責選出主庫;任一地失效仍是多數
兩地皆可供應
推播服務即時資料送到 App
開發者負載平衡入口 · 臺北 / 高雄SSE 即時串流、時間同步TPE-1 · KHH-1核心節點 · 臺南 / 東京資料 APITNN-1 · TYO-1
- 主鏈路
- 備援鏈路
- 跨站同步與去重
- 資料庫複寫與共識
- 對外分發
兩條上行鏈路同時傳送,不是故障時才切換。每條鏈路以 UDP 為主,連續逾時時改用 WebSocket。
資料怎麼從測站到你手上
Section titled “資料怎麼從測站到你手上”- 測站量測:感測器以 50 Hz 取樣三軸加速度,在測站端換算 JMA 震度,每 500 ms 送出 2 個封包(震度與感測資料)。
- 雙上行:每台測站同時連線臺南(主鏈路)與東京(備援鏈路)。兩地都收到每一個封包,不是故障時才切換。
- 傳輸與驗證:每條鏈路以 UDP 為主,250 ms 內沒收到確認就重傳,最多 1 次。每個封包與確認回覆都有 HMAC-SHA256 簽章,伺服器會拒絕重放的封包。
- 跨站同步:兩座核心節點以訊息叢集互聯,互相同步震波與震度並去除重複,同一筆資料不會被處理兩次。
- 各自運算:兩地各有即時震度(RTS)與即時波形服務,訂閱同一份即時資料、各自產出結果。震波與震度也寫進各節點自己的時序資料庫,保留 7 天。
- 分發:即時資料經訊息叢集廣播,由推播服務送到 App。開發者經臺北、高雄的負載平衡入口取得 SSE 即時串流與時間同步;地震報告等資料 API 由臺南、東京節點提供。各服務的網址見伺服器與 Base URL。
所有伺服器每分鐘對時,並對齊樣本的時間戳,跨節點的時間一致。你的程式要比對資料時間時,可以用時間同步端點校正本機時鐘。
異地備援怎麼運作
Section titled “異地備援怎麼運作”| 節點 | 地點 | 角色 | 對外提供 |
|---|---|---|---|
TNN-1 |
臺南 | 核心節點(測站主鏈路)、中繼資料庫、共識節點 | 資料 API;氣象與地圖圖磚只在這裡提供 |
TYO-1 |
東京 | 核心節點(測站備援鏈路)、中繼資料庫、共識節點 | 資料 API |
TPE-1 |
臺北 | 負載平衡入口、共識節點 | SSE 即時串流、時間同步 |
KHH-1 |
高雄 | 負載平衡入口 | SSE 即時串流、時間同步 |
各節點的網址見伺服器與 Base URL。
每台測站維持兩條上行鏈路:主鏈路連到臺南,備援鏈路連到東京,兩條同時傳送。其中一地斷線或網路壅塞時,另一地已經有同一份資料,不需要等待切換。
每條鏈路各自決定傳輸方式:
- 平時用 UDP,延遲低,重傳次數可控。
- 連續 4 次逾時,該鏈路改用 WebSocket(TCP)。
- 使用 WebSocket 期間每 5 秒以 UDP 探測,連續 3 次成功就切回 UDP。
伺服器以平滑後的 RTT 與 5 分鐘內的遺失率追蹤每條鏈路的品質。
兩地各自運算
Section titled “兩地各自運算”臺南與東京各有一套完整的即時處理:接收測站資料、即時震度(RTS)、即時波形、時序資料庫。兩地處理同一份資料,不依賴對方;任一地停擺,另一地照常產出。
跨站同步與去重
Section titled “跨站同步與去重”兩座核心節點以訊息叢集互聯,同步彼此收到的震波與震度。同一個封包會經由兩條鏈路分別抵達兩地,同步時會去除重複,每筆資料只處理一次。
資料庫自動故障轉移
Section titled “資料庫自動故障轉移”中繼資料庫(PostgreSQL)在臺南與東京各有一座,由 Patroni 管理同步串流複寫:
- 主庫失效時,備庫自動提升為新的主庫。
- 由誰擔任主庫,由臺南、東京、臺北三地的多數決共識(etcd)決定。三地中任一地失效,剩下兩地仍是多數,選舉照常進行。臺北提供第三個共識節點,讓兩座核心節點之一失效時仍能形成多數。
- 每座節點的路由層(HAProxy)只把寫入導向目前的主庫。
開發者連線的入口也分散在不同地點:
- SSE 即時串流與時間同步:臺北(TPE-1)、高雄(KHH-1)兩個負載平衡入口,提供相同的路由。
- 資料 API:臺南(TNN-1)、東京(TYO-1)兩座核心節點直接提供;另有由 DNS 分配節點的 Auto 名稱。
入口不會替你的程式換節點。Auto 由 DNS 分配,節點故障時 DNS 不一定立刻移除它。要不受單一節點影響,請照自行切換 Base URL 在用戶端準備備用的 host。
節點故障時會發生什麼
Section titled “節點故障時會發生什麼”| 情況 | 會發生什麼 | 你該怎麼做 |
|---|---|---|
| 一座核心節點停擺(臺南或東京) | 測站資料仍經另一條鏈路送到另一座節點,即時震度與波形照常產出。直接連到停擺節點的請求會失敗;經 Auto 的請求在 DNS 移除該節點前也可能失敗。 | 資料 API 依自行切換 Base URL 換到另一個節點(TNN-1 ↔ TYO-1),只在連線錯誤、逾時或 5xx 時換。SSE 串流若中斷,依重新連線的規則重連。 |
| 臺南節點停擺 | 同上。另外氣象與地圖圖磚只在臺南提供,這段期間無法使用。 | 這些端點沒有備援節點,換 host 也無法取得。請在畫面上標示資料暫時無法取得,稍後再試。 |
| 上行鏈路變差或中斷 | 該鏈路自動改用 WebSocket,恢復後切回 UDP。另一條鏈路照常傳送,兩地都持續有資料。 | 不需要處理。對外的 API 與串流格式不變。 |
| 資料庫主庫失效 | 備庫自動提升為主庫,各節點的寫入改導向新的主庫。 | 通常不需要處理。切換期間若收到 5xx,依自行切換 Base URL 的規則重試。 |
| 一個共識節點失效 | 剩下兩地仍是多數,主庫選舉照常進行。 | 不需要處理。 |
| 負載平衡入口停擺(臺北或高雄) | 另一個入口提供相同的路由。經 Auto 的連線在 DNS 移除故障入口前可能失敗。 | SSE 斷線後依 retry: 3000 等 3 秒重連;連續失敗數次(例如 3 次)就換到另一個入口(TPE-1 ↔ KHH-1)。時間同步也一樣換入口。 |
- 異地備援涵蓋地震即時資料:測站、震度、波形與地震報告。
- 氣象,以及雷達、衛星、風場等地圖圖磚,目前只在臺南節點提供,沒有異地備援。臺南停擺時這些端點無法使用,見僅 TNN-1 提供的路由。
- Auto 名稱由 DNS 分配節點,節點故障時不保證立即移除。要不受單一節點影響,用戶端需要自行切換 host。
- 本頁說明的是架構設計,不代表可用率或切換時間的承諾。
