連鎖餐飲後臺大改造:一個查詢拖垮全站的真實案例
某連鎖餐飲品牌的訂單系統從每小時被打爆296次查詢到穩定執行,這篇拆解我們踩過的坑:連線池耗盡、貨到付款漏洞、報表算錯錢,都是真實踩雷經驗。
- 首頁商品查詢沒加快取,尖峰時段連線池被打到耗盡,全站連帶掛掉
- 貨到付款用訂單狀態判斷會計算錯誤,改用付款方式判斷才對得上帳
- 前臺一個小元件例外處理沒做好,會被放大成整頁500錯誤

某天下午五點,一家連鎖餐飲品牌的官網開始不定時出現502。客服開始接到訂單訂不了的電話,工程群組裡瀰漫著一股「是不是又中獎了」的低氣壓。查了半天,兇手不是駭客攻擊,是首頁一個商品查詢,每次有人開首頁就打一次資料庫,尖峰時段一小時被打了將近300次,資料庫連線池直接見底。
連線池耗盡,牽連的比你想像的多
這種案子最麻煩的不是修主兇,是修完主兇之後發現一堆枝微末節被連坐。這次的附帶損害是購物車右上角的數字徽章。它平常只是個小元件,背景默默去查有幾個商品在購物車,本來壞了也不影響其他功能。但因為框架的例外處理寫得太粗暴,只要這個小查詢因為連線池耗盡而炸掉,整個網頁就被強制導向錯誤頁,等於一個配角掛了,主角也跟著陪葬。
- 根本解法:幫首頁查詢加上短時間快取(這案例用3分鐘),把尖峰查詢量從每小時近300次砍到20次以下
- 防呆解法:區域性元件的例外,不該影響整頁渲染,該吞的錯要吞掉,只記錄不炸版
- 延伸動作:確認快取重建有上鎖,避免快取一過期,瞬間又被大量請求打穿重演事故
貨到付款,算錯的不是技術,是邏輯
另一個常見的踩雷點,是用「訂單狀態」去判斷一筆貨到付款訂單算不算已收款。聽起來合理,實際上很容易漏。因為出貨動作會改變訂單狀態,但不會改變付款時間欄位,導致系統一出貨就把這筆訂單同時漏出「營收」跟「未收款揭露」兩個報表,錢憑空消失又憑空出現,對帳的人會瘋掉。
正確做法是回歸業務本質:判斷這筆訂單「用什麼方式付款」,而不是「現在走到哪個狀態」。狀態只拿來排除已取消、已退貨、超過取件期限這些不該算數的例外情況。這個修正沒有換任何新技術,純粹是把判斷邏輯的立足點從「流程」搬回「事實」。
系統邏輯錯了,不會跳錯誤訊息,只會默默算錯錢。
每日報表跑19秒,只因為忘記把運算丟給資料庫
這家品牌的每日營運報表,原本要跑將近20秒才出得來,慢到值班人員每天早上都要罰站等報表。追下去發現,程式把整張點數交易明細表連同會員資料整包撈進應用程式的記憶體,再用程式邏輯一筆一筆去找每個人最新的點數餘額。這種寫法在資料量小的時候看不出問題,資料一多,就是拿著湯匙挖游泳池。
這些坑教會我們的事
系統最佳化不是換更貴的主機,是找到那個一直被忽略的笨方法。