健保卡、報稅、搶票全塞爆:台灣政府網站的「尖峰流量」是架構問題,不是運氣問題
每逢報稅截止日、口罩預購、演唱會搶票,政府與半官方系統幾乎必定癱瘓。問題不在伺服器太少,而在傳統「集中式、同步、資料庫為中心」的架構,天生無法承受瞬間百倍流量。從佇列、快取、無狀態設計到邊緣節點,解方其實早就存在,卡住的是採購與治理。
凌晨十二點整,搶票系統開賣,三十秒後畫面轉圈;五月三十一日晚上,報稅網站回傳錯誤;疫情高峰那幾天,預約平台連續掛掉。台灣人對這些畫面太熟悉了。但問題來了:這些系統平常都好好的,為什麼一到關鍵時刻就崩?
答案很簡單,卻很少被講清楚,因為它們的架構是為「平均流量」設計的,而癱瘓永遠發生在「瞬間峰值」。
真相一:流量不是線性成長,是一秒內爆炸百倍
以量級來看,多數政府網站日常同時上線人數可能只有數千等級,但搶票或報稅截止前一小時,瞬間請求可以暴增到平常的數十倍甚至百倍。傳統三層式架構(網頁伺服器、應用伺服器、資料庫)的瓶頸,幾乎永遠卡在最後一層:資料庫的連線數與鎖。一千個使用者同時查同一張表,資料庫不是變慢,是直接排隊到逾時。這不是硬體不夠,是同步架構的天性。
真相二:少了一個排隊機制,等於讓千萬人同時擠一扇門
商業搶票平台(無論成功與否)至少做了「虛擬等候室」,把瞬間洪流轉成有序佇列,系統按消化速度放行。這在分散式系統裡是教科書級的手法:訊息佇列、背壓控制、流量整形。政府系統常見的做法卻是「加伺服器」,水平擴展了前端,後端資料庫照樣單點。等於把高速公路從三線拓寬成十線,交流道還是那一個。
真相三:CAP 定理不會因為採購公告而失效
尖峰時刻,系統被迫在「一致性」與「可用性」之間選邊。搶票需要強一致(一張票不能賣兩次),所以犧牲可用、讓人排隊是正確設計;但查健保快譯、查補稅金額這種唯讀資料,完全可以用多層快取與內容傳遞網路(CDN)把 90% 以上的請求擋在源頭之外。多數塞爆的案例,是該快取的不快取、該排隊的不排隊,一刀切的架構承擔了兩種完全不同的負載。
關鍵解方:把「尖峰」當設計前提,而不是例外
技術上,無狀態前端、自動伸縮、讀寫分離、事件驅動後端,都是十年以上成熟工程。真正的瓶頸在治理:政府採購以「人月」計價、驗收以「功能清單」勾選,沒有一欄叫「十萬人同時湧入時的行為」。業內普遍觀察是,得標廠商沒有誘因為一年只發生一次的尖峰多花成本。國際上,愛沙尼亞的 X-Road 把服務拆成小而獨立的節點,英國 GOV.UK 用靜態化與快取撐住選舉夜流量,方向都一樣:假設尖峰一定會來。
下一次系統癱瘓時,真正該問的或許不是「為什麼又掛了」,而是:我們的採購制度,付得起「不掛」的價格嗎?