這週 3Q 工程團隊在五個系統裡先後碰到同一類問題:邊界條件被假設覆蓋了,直到真實流量或時間把它逼出來。有 Python GIL 把整個後端凍住兩分鐘的、有 NULL 被當作零悄悄灌入幽靈電費的、有賽後仍空轉呼叫外部 API 的、也有兩次看似相同的失敗其實來自兩個完全不同根因的。這些案例的共同點不是技術棧,而是診斷方法:先找到問題真正的邊界在哪,再決定從哪裡下刀。
阻塞式 SDK 讓後端凍結兩分鐘,TCP 探測才是正確的快速失敗門衛 #
自動交易後端在特定時段完全無響應,前端所有頁面看起來沒有資料。第一直覺是資料庫,但驗證後 MySQL 完全正常,十五支 API 全部可用。問題其實出在上游券商主機連不上——Python SDK 執行登入時持有 GIL(全域直譯器鎖),整個程序凍住等候,實測卡滯超過兩分鐘;而每次頁面載入都會觸發新的登入嘗試,形成連鎖凍結效應。
評估過「把 SDK 登入丟進背景執行緒加逾時」,但實測主執行緒仍凍結七十秒——確認這條路不通,因為鎖住的是直譯器本身而非 I/O,執行緒切換救不了。最終做法是在碰 SDK 之前先做純 TCP 探測:三秒確認上游不通就直接記失敗、進入五分鐘 cooldown,完全不碰 SDK。同步加入「同時只允許一個執行緒登入」的防衛,其餘請求立即走備用資料來源。驗證結果:原本 135 秒的凍結縮短為 3 秒即放棄,cooldown 期間後續請求零延遲,系統持續對外服務。
對任何依賴第三方阻塞式 SDK 的系統,應在 SDK 呼叫前加 TCP 探測作為快速失敗門衛,而非依賴 SDK 內部的逾時機制——SDK 的逾時不一定會釋放鎖。這個模式在任何需要和外部系統(金融 API、設備控制器、硬體驅動)溝通的 Python 後端都適用。
NULL 被當成零:一個填補策略讓電費帳單多出幽靈度數 #
太陽能監控系統的計費後端長期出現異常「幽靈度數」,帳單數字和實際用電兜不上。這類問題最難的地方在於它不報錯、不當機,只是數字慢慢偏移,要等到有人認真比對才會發現。
Solar Monitor 系統溯源後確認根因:Modbus 輪詢偶發 socket timeout,該筆讀值回傳 NULL;計費函式以 COALESCE(NULL, 0) 將 NULL 填為零,導致下一筆正常讀值被整個算成新增用電。這個機制在兩個月內觸發三次,分別灌入 15.1 度、2 度、21.5 度的假度數到對應的電費級距。修法是讓差分函式直接跳過 NULL 樣本、銜接前一筆有效值,而不是以零填補。同步釐清了一個常見誤解:計費起算點的「零」與 timeout 造成的 NULL 是兩件完全不同的事,不應混為一談。
任何以差分計算累積量(電量、流量、計數)的系統,NULL 填零是危險的預設值,應改為跳過或以前值接續。越是「不報錯只偏移」的 bug,越需要在設計時就建立定期比對機制,而非等帳單核對才發現。
賽後空跑三個月:靜態化比停容器更能同時保住 SEO 與資源 #
2026 FIFA 賽後展示站在賽事結束後仍以即時代理模式持續運行,每次訪問都呼叫多個外部 API,對外回應時間近兩秒,記憶體持續佔用,CPU 有穩定負載。問題不是系統故障,而是賽後定格機制當初未被觸發,從七月空跑至今。直接停掉容器看似最快,但調查後發現該網址被多個對外頁面引用,包含官網案例頁、結構化資料、sitemap、排名較高的技術文章,以及對外提案書的實績列表——貿然停服等於死鏈連鎖,影響 SEO 積累與客戶可信度。
選擇「保留網址、替換內容層」的方案:抓下最終賽事資料存成靜態檔,把原本的 Node.js 即時代理容器替換為純 nginx 餵靜態,反向代理那層零更動,網址與埠號完全不變。結果對外回應從 1.9 秒降至 0.2 秒、記憶體從 81 MB 降至 12.8 MB、CPU 歸零、外部 API 呼叫歸零。畫面比對與原版一致,零 console error。原始即時代理設定另存備份,日後若需復活只需換回重新建置。
對有外部依賴的時效性服務(賽事、活動、限期展覽),「定格靜態化」比「直接下架」更能同時滿足 SEO 保留與資源釋放兩個目標。這個模式應該在設計階段就建立觸發機制,而非靠人工補救——賽後三個月空跑呼叫外部 API 是可以避免的。
兩次下單失敗,症狀相似但根因完全不同 #
期貨策略在兩個不同交易日分別出現下單失敗,表面症狀相似——都是委託被券商拒絕、系統告警觸發。直覺是同一個機制壞了,但如果假設成立,理論上兩次的修法方向應該一樣。
Futures Lab 系統的診斷原則是:多個症狀在確認有共同根因之前,必須逐一獨立追查。查券商原始回覆後,確認兩次是兩個完全不同的根本原因:第一次是保證金不足,第二次是策略商品從微型合約換成標準合約,名目價值驟增,直接觸發額度上限。是客戶操作導致的邊界碰撞,不是系統 bug。同步重設計告警訊息:加入三個層次——券商錯誤碼原文、白話解釋(只對已確認含義的碼才翻譯)、明確的處置指引,加上連續失敗次數,讓使用者能區分持續中的單一事件與多個獨立事故。
面向非技術使用者的告警,應在資訊正確的前提下給出「下一步行動」,而非只呈現系統狀態碼。診斷多症狀問題時,「它們應該是同一件事」是最常見的過早收斂——每個症狀都需要對齊自己的 root cause 再合併,而不是倒過來。
舊版本的防禦性補丁,在新呼叫模式下反過來成為 bug 來源 #
Claude Nexus 平台的 chat_server 在日誌裡持續出現子行程異常終止(exit 143),三十天累積六十筆錯誤紀錄,幾乎天天有,卻因為是「非關鍵路徑的失敗」而不易察覺。
追查到一段 SDK 舊版本時代的防禦性補丁:當年 aclose 不會回收子行程,所以靠「查詢前後子行程集合的差集」把新出現的子行程強制終止。後來架構改成兩個請求同時打出,兩發在同一瞬間進來,先完成的那發就把另一發的 CLI 子行程也一起殺掉,造成 exit 143。現行版本的 SDK transport 已自己處理子行程回收,這段補丁早就無用,只剩下副作用。根治方式是直接刪除整段補丁,不需要替代方案。
版本升級後,舊的防禦性補丁必須同步審查是否仍有存在必要。補丁在當年解決問題,不代表它在新版本或新呼叫模式下仍然安全——特別是在並發架構下,時序假設往往會悄悄失效。
本週其他進展 #
- Claude Nexus session registry 洩漏修復 — 用戶直接關分頁時,停放區的 session 被 terminate 後 SDK client 與子行程未清理,抽出共用的 teardown 函式後讓所有終止路徑都走完整清理序列。
- Claude Nexus handoff 補入本機未同步訊息 — 舊邏輯從知識庫抓完歷史後直接收尾,遺漏知識庫同步延遲窗口內的訊息;改為讀本機 JSONL 尾端、以內容比對找差量後補入。
- Claude Nexus 機群全量升級至最新 CLI 與 SDK 版本 — 解決升級程序因瀏覽器連線中斷而中止的問題,改為伺服器背景獨立執行並記錄進度,完成九台機群的全量升級。
- eMobile 電子發票系統發布 HQ 1.4.24 與 B2B 1.8.14 — 本版修復密碼輪換後因 Cloudflare clearance cookie 被清除導致人機驗證失敗的問題,同步改善 4G 斷線警示的狀態機與同步週期,並放寬發票上傳限制條件。
- Solar Monitor BMS 並聯匯流異常根因分析完成 — 確認 p1/p3 電芯交界接觸電阻達正常值二十倍以上,導致 BMS 均衡演算法誤判並引發湧流告警鎖住;提出拆除疊層結構、以足截面導體直接銜接的修復方案與驗收標準。
- Solar Monitor 容量座標系統依實測數據重建 — 以兩次實測錨點重建有效容量基準,一次性更新後端規劃器、前端顯示常數與 AI 簡報文字,並以 docker rebuild 固化所有改動。
- sunnypilot 縱向控制三項行為調整 — 以實測資料為錨點調整防蠕動門檻、彎道加速邏輯與跟車緩衝,並確認彎道追蹤瓶頸根因在積分凍結與前饋低速估值不足,為後續修法提供明確方向。
- ESP32-C3 LED 中繼韌體完成驗收並部署 — 完成 WiFi 中繼韌體,以拔插冷開機測試確認內建 USB reset 行為與正式斷電不等價;完成三項驗收測試,正式部署取代原有網路線方案。
- 鴻順機械官網「捲對捲」關鍵字能見度修復 — 確認「捲對捲」在網站可見內文中完全缺席、GSC 曝光量為零,在核心技術頁新增 FAQ 可見區塊(含四種搜尋變體共七次出現)與 FAQPage 結構化資料,已提交 GSC 重新建立索引請求。
- Invoice Lottery 預覽圖防呆機制上線 — 設計 preview- 前綴命名規範與後台警示,讓版權尚未買斷的圖庫預覽圖在系統層面可見;恢復十八張客戶指定預覽圖並完成行程圖片功能實裝。
- Futures Lab 幽靈委託清理與績效記帳修正 — 清理兩次下單失敗產生的零成交幽靈紀錄共三十六筆,備份保留,策略真實勝率還原至正確數值。
- 出勤管理系統完成補登、修改與機關稽核隔離模組 — 實作打卡修改與整日補登兩個入口,首次修改時做快照保留原始稽核鏈;機關角色只見修改後時間,管理員看完整修改痕跡,以角色控制渲染欄位而非另備資料。
- LcbProduction 儀表板雙路徑計算邏輯統一 — 首次載入與定時刷新兩條路徑各自維護一份計算,歷次功能擴充只更新其中一條,導致某部門數字差距達五千筆以上;本週統一兩條路徑的計算來源。
- LcbProduction 烘胚台車掃描流程重構 — 入室不再記錄人員、改由台車裝載者作為追溯依據,移除一道操作步驟;同步修正跨天接續裝載的查詢時間邊界,以及儲存前的業務規則伺服器端驗證。
本週技術心得 #
這週看下來,讓我們花最多時間的問題,幾乎都不是「沒想到」,而是「曾經想到、但沒有落地驗證」。Python GIL 的阻塞行為是已知的,但在實際系統裡測出 135 秒凍結才讓修法方向變得清晰。NULL 填零的危險是基礎知識,但要等帳單出現異常度數才開始追查。靜態化比停容器更好這個判斷也不難,但如果沒有先去查那個網址被引用了幾次,「停容器最快」很容易就被執行了。
對中小企業的資訊系統來說,這類邊界條件的代價特別高——因為系統規模不大,很少有足夠的監控覆蓋率去在問題擴大前主動發現它。我們在這些案例裡慢慢形成的習慣是:改動前先問「這段邏輯在什麼情況下會走到非預期的路徑」,而不是只問「正常情況下能不能跑通」。驗收條件必須包含邊界情境,不能只有 happy path。這件事說起來不難,但在緊繃的開發節奏下,第一個被省掉的往往就是這個步驟。
本文是 3Q 工程團隊的每週技術進度整理,由 Claude 協助編寫。內容聚焦技術類型與通用心得,不含客戶資訊。
