2026年9月13日13 分鐘技術週報 · 工程進度

技術週報 2026-09-06 ~ 2026-09-13:靜默失效的四種工程陷阱

這週我們在四個不同專案裡,各自挖到了同一類型的問題:系統看起來正常運行,其實早就停擺或在原地打轉。一個 batch worker 跑了五個月卻沒往前推進一步;一支桌面程式的計時器被作業系統靜默降速十倍;一次正確的設定修改,被每日自動排程悄悄還原;一筆多年前的手動覆寫,在對方搬遷機房後變成靜默地雷。這四個案例的共同教訓是:「沒有報錯」不等於「有在運作」,真正的可觀測性需要進度錨點,而不只是存活狀態。

3Q 編輯部(AI 協作)

技術週報 2026-09-06 ~ 2026-09-13:靜默失效的四種工程陷阱 — 文章主視覺

這週我們在四個不同專案裡,各自挖到了同一類型的問題:系統看起來正常運行,其實早就停擺或在原地打轉。一個 batch worker 跑了五個月卻沒往前推進一步;一支桌面程式的計時器被作業系統靜默降速十倍;一次正確的設定修改,被每日自動排程悄悄還原;一筆多年前的手動覆寫,在對方搬遷機房後變成靜默地雷。這四個案例的共同教訓是:「沒有報錯」不等於「有在運作」,真正的可觀測性需要進度錨點,而不只是存活狀態。

worker 持續在跑,但進度凍結了五個月 #

知識庫的向量化 worker 從四月下旬起實際上已停止推進——但它沒有報錯、也沒有崩潰,監控指標一切正常。五個月後才發現:4/22 之後的三十幾萬筆對話全無向量,語意搜尋長期退化成純關鍵字比對,用戶完全無法察覺差異。

追查後找到根因:批次查詢以 ID 由舊到新排序,加上內容為空的訊息被標為「已處理」卻未排除,導致每一輪都撈到同樣那 50 筆死列,永遠在原地迴圈。修法是排除已標記列、改為新到舊優先取樣,並把批次間隔從 60 秒壓縮到 5 秒。補算速度從每天約 3.6 萬筆提升到約 8 萬筆,舊帳清完時程從十天縮短到四到五天。這個問題之所以難察覺,是因為我們只監控了 worker 的「活躍狀態」,沒有設立「推進進度」的錨點——worker 跑著,但永遠跑在同一個地方。

Batch Worker 原地迴圈示意:活躍狀態與推進進度是兩個不同的指標,只監控前者無法發現後者卡住。
Batch Worker 原地迴圈示意:活躍狀態與推進進度是兩個不同的指標,只監控前者無法發現後者卡住。

任何批次作業都應設計可量測的進度指標(例如「本輪處理了多少筆新資料」),而非只看「有沒有在跑」。原地迴圈是 batch job 最隱蔽的一類故障,存活探針偵測不到它。

切到背景視窗,30 秒等待變成 4 分半 #

電子發票桌面應用(eMobile)在執行 Turnkey 上傳時需要等待約 30 秒,這在前台測試時完全正常。但使用者反映實際操作中等了好幾分鐘才完成,問題只在「切換到其他視窗」時才會發生,純前台測試永遠重現不了。

追查後確認是 Chromium 的 intensive throttling 機制:當 Electron 視窗被隱藏超過一段時間後,所有計時器會被降速至每分鐘一次,造成 30 秒的等待實際上拖到 4 分半以上。修法是在 webPreferences 加入 backgroundThrottling: false,讓計時器不受視窗可見狀態影響。HQ 與 B2B 兩支程式均修正,分別交付新版本。

Electron 應用中任何依賴計時器的非同步流程,都應在設計初期考慮背景節流的影響。這類問題在開發時難以察覺,因為測試時視窗幾乎都在前台;只有在使用者的真實操作習慣(切換視窗)下才會觸發,屬於「環境行為與程式假設不一致」的典型案例。

改好的設定,隔天被自動還原 #

一次網域遷移改名兩天後悄悄回滾,起初以為是手動操作失誤。沒有任何報錯、沒有版控衝突,設定就這樣神不知鬼不覺地回到舊狀態,讓問題重複出現兩次才開始懷疑是系統性原因。

追查發現根因是架構上的認知偏差:原始碼在開發伺服器(source of truth),另一台是純部署鏡像,兩者之間有每日 cron 執行的 rsync(帶 --delete 完全覆蓋)。上次修改只作用在部署端,隔天 cron 一跑就被源頭蓋回。診斷路徑是:先懷疑 rsync 方向 → 查 crontab 確認 --delete flag → 比對兩端時間戳對齊落差。確認根因後,在源頭完成修改,並掃描所有自動化腳本裡的硬編碼舊網域字串(橫跨多個自動生成流程),防止舊名繼續出現在自動產出的內容裡。

單一真相來源原則:只有在源頭操作的修改才能存活過下一次自動同步,直接改下游等於在沙灘上寫字。
單一真相來源原則:只有在源頭操作的修改才能存活過下一次自動同步,直接改下游等於在沙灘上寫字。

CI/CD 管道中若存在「定時單向同步」,任何繞過源頭直接改下游的操作都是暫時的,會在下次同步時消失。排查這類 regression 要先問「這個值是被誰產生的」,而不是「被誰持有的」。單一真相來源(source of truth)必須被所有人明確知道,並且所有修改都要從源頭出發。

一筆多年前的設定,在對方搬遷機房後變成地雷 #

客戶自架郵件系統突然無法寄信給特定網域的收件人,錯誤一律顯示「Relaying denied」。初步看起來像是對方把來信當成非法轉信請求拒絕,但仔細想又不太對——為什麼只有這個網域失敗?

排查時在郵件伺服器的「預查 MX 設定」功能裡發現一筆靜默的手動覆寫:把特定郵件網域指向一個固定 IP,讓送信引擎跳過 DNS 查詢直接送達。這筆設定在當年建立時是對的——那個 IP 確實是對方的收信主機。但對方在 9/1 將商務郵件的收信主機遷移到新機房,這筆冰封多年的設定才從「幫手」變成「路障」——信被送到已不再負責收信的舊主機,對方當然拒絕轉發。修法是刪除那筆覆寫,讓送信引擎回歸即時 DNS 查詢,切換後立即恢復正常。

「寫死外部第三方 IP」是常見的短期偏方,能即時解決當下問題,但它把對方的基礎設施狀態凍結在自己的設定裡。一旦對方搬遷,就變成靜默地雷——信退掉不影響系統本身,沒人會第一時間想到去那張設定表裡找原因。外部系統的連線設定應優先依賴 DNS,而非固定位址。


本週其他進展 #

  • Claude Nexus 知識庫連線池三層治本 — 完成並發守門(同一 user 已有處理中執行緒直接跳過)、向量化作業改為逐筆 commit、以及 idle-in-transaction 逾時設定,5 條並發請求中 1 條執行、4 條正確跳過,解決先前連線池耗盡問題。
  • Claude Nexus 跨 Session 上下文自動注入 — SessionStart hook 加入「上一場收尾原文」自動注入機制,開啟新 session 時即有可用的工作結論,不需依賴模型記憶或手動貼上,resume 與 compact 模式下不觸發。
  • 3Q夥計 chat_server 大型 session 崩潰修復 — 在三條共用入口的決策點加入檔案大小判斷,超過門檻自動走 handoff 開新 session,門檻依實測分布制定(中位數 6MB、90th percentile 22MB),4 個邊界案例全部 PASS,diff 38 行外科手術式修改。
  • eMobile B2B 空白發票非即時查詢自動化 — 實作「偵測線上查詢上限 → 自動改走非即時申請 → 輪詢 → 下載 CSV」完整內部流程,對使用者仍是單一按鈕操作,輪詢間距依實測(2 秒)而非平台公告(每 2 小時)設計。
  • eMobile 折讓證明單列印與 PDF 匯出功能補齊 — 補齊前端按鈕與後端 handler,支援列印、另存 PDF、開啟預覽三種模式,稅額計算抽成共用函式讓 XML 與 PDF 共用同一套邏輯,消除兩端各算產生對帳差異的風險。
  • 寄售管理系統 101 通路漏單根因修復與部署 — 補齊應用層通路識別邏輯與 SQL WHERE 條件兩個層次的比對缺陷,加入重複匯入防呆,補登後驗證四張出貨單全數正確抓到且不誤抓其他通路,完成 PyInstaller 全新建置部署。
  • Solar Monitor 電費帳單計費起始日 bug 修復 — 修正帳單起始日推算邏輯,排除校正讀數對計費邊界節點的干擾,rebuild 容器部署,並回補歷史上被同 bug 污染的舊資料。
  • 股票系統已驗證股票豁免邏輯修復 — 補足每日觀察池重建的豁免條件,讓已驗證股票在持倉賣出後仍受保護不被清除,同時修正前端 AI 建議過期未標示問題,補跑遺漏的當日分析批次。
  • 輿情監控系統 PTT 靜默失敗修復,部署 v14 — 補上 Serper API 路徑的錯誤處理,API 額度耗盡時正確記錄錯誤訊息而非靜默記成成功,消除「儀表板顯示正常、實際已停擺」的可見性盲區。
  • 發票抽獎系統美食地圖後台 CMS 建置 — 將 49 家店的硬編碼資料遷移至新建資料表,搭配後台介面,主辦端可自行完成店家新增、編輯、上下架與分類管理,資料表採純 CREATE TABLE migration 不觸碰既有資料。
  • 發票抽獎系統 Android 拍照與條碼辨識修復 — 拆分拍照與選擇檔案兩顆獨立按鈕,修正縮圖策略過激導致條碼模糊的問題;實測 5 張發票辨識率從 0/5 提升至 4/5,每張耗時從 7–29 秒降至 0.3–3 秒。
  • 客戶管理後台撤銷贈品發放功能上線 — 採軟撤銷設計保留原始記錄與時間戳,時間感知確認框在撤銷非當日發放時自動跳出警告,前端依權限決定是否渲染操作欄位,後端強制驗權,限量庫存自動回補。
  • YISEN 0.7.20 版本打包交付 — 修正折讓媒體申報檔誤被拆成進銷兩份(導致匯入財政部文中系統缺行)、PDF 被佔用時改為自動另存附時間戳檔名,連同五項累積修正一起打包,逐一比對包內檔案與原始碼一致性。
  • 生產管理系統掃描頁面分頁效能優化 — 四個掃描頁面改為兩段式查詢(COUNT 算總頁 + OFFSET/FETCH 只取當頁 50 筆),首次載入資料傳輸量從全量壓縮至最多 50 筆,中文版與印尼版共 8 個檔案同步更新。
  • sunnypilot 雷達距離量測方法建立 — 以車牌尺寸為標尺,透過影片對照建立可重用的距離量測方法,驗證雷達 dRel 有系統性偏近誤差,蒐集 26 個停車事件樣本,供後續停車距離參數調整使用。
  • CEH 刷題應用上線 — 完成 CEH 797 題線上刷題應用,支援中英雙語與進度紀錄同步,依存取來源區分認證方式(內網免密、外網帳密保護)。
  • 國際加盟展主持人用商品簡報交付 — 共 10 張投影片(PPTX+PDF),依舞台動線拆分頁面結構,現場管制資訊轉為主持人標準答案底注,PPTX 與 PDF 同步交付。

本週技術心得 #

這週橫跨六七個專案,我們反覆踩到同一類問題的不同變體:一個東西「看起來正常」,但實際上早就沒有在推進。Batch worker 的存活探針顯示它在跑,但沒有進度錨點;郵件系統正常收發大部分信件,卻有一個靜默的路由例外;觸發條件不對,timer 被作業系統靜默降速;修改作用在下游,每日排程把源頭蓋回來。這四件事的根本問題不是技術選型,而是「可觀測性的設計盲區」。我們在系統裡設計了很多「還活著嗎?」的探針,但很少設計「有沒有往前走?」的探針。對 IT 顧問或自建系統的中小企業來說,這個教訓有很實際的意義:維護的成本往往不是修錯,而是找到「沒報錯但也沒在動」的問題。解法不是加更多監控,而是在設計期就定義清楚「什麼叫做這個流程有在正常推進」,並把這個定義變成可量測的指標,而不只是服務的存活狀態。


本文是 3Q 工程團隊的每週技術進度整理,由 Claude 協助編寫。內容聚焦技術類型與通用心得,不含客戶資訊。

有類似的問題想解決?

先聊聊你的狀況,我們給你可執行的方向。諮詢免費,依工時報價。

3Q · 摩葳實業 / 牛寶創意科技社 / 倍新有限公司 — 企業 IT 系統,做了 23 年