第1章

城市的夜像一張反覆覆寫的螢幕,亮處是霓虹與車燈,暗處是無聲吞吐的黑影。林知夏下班時走得很快,風從玻璃幕牆間的縫隙鑽出來,像有人在背後輕輕推她一把。她把外套拉鍊拉到下巴下麵,仍舊覺得冷。她冇有抬頭看高樓的頂端,因為那上麵總掛著“正在維護”的字樣——自從那場事故之後,整座城市的係統彷彿都變得謹慎起來,連廣告牌都像在等某種命令。

她的手機在掌心震動了一下。

訊息來自工作群:研發部線上緊急故障。

林知夏是產品經理,不是運維,也不負責後端架構。但她在這家公司裡總擔著一個“補鍋”的角色。因為她擅長把一堆看似互相矛盾的日誌、需求、運營數據拚成一張能落地的路線圖。她被叫去的時候,往往意味著事情已經超過工程師能內部消化的範圍,至少需要一個人把“發生了什麼”說清楚、把“接下來怎麼做”寫得足夠讓老闆點頭。

群裡又刷出一條。

運維說:淩晨兩點半的版本更新觸發了異常回滾,現在線上部分用戶無法完成支付。影響範圍在擴大,但目前暫無安全風險確認。

林知夏盯著最後那句“暫無安全風險確認”,眼皮一跳。安全風險四個字像硬幣一樣反光,晃得人心裡發緊。她知道這種話通常意味著:監控還冇看到確定的壞事,但已經有一些信號讓人不敢掉以輕心。

她把揹包甩到肩上,快步穿過寫字樓長廊。走廊裡燈光偏冷,地麵反射出她的影子,像一個被拉長的問號。辦公室的門冇有完全關上,裡麵傳出鍵盤敲擊與壓低的爭論聲。

“知夏來了?”有人抬頭,是技術支援組的小高。他總是把“客氣”掛在臉上,像把同一把鑰匙插在不同的門鎖裡。他的眼睛裡卻有疲憊,“我們需要你看一下用戶側的行為鏈路,判斷是不是產品規則改動導致的。”

“我馬上。”林知夏把電腦包放到工位上,打開螢幕。螢幕上彈出一個實時麵板:支付失敗率從0.2%上升到3.8%,呈台階式攀升。她冇有直接看那串數字,而是先看失敗率上升開始的時間點。淩晨兩點半,正是上線視窗。

時間點和版本更新觸發回滾完全一致。

她點開日誌摘要,裡麵有一串並不顯眼的錯誤碼,但被標了紅色:REQ_CONSISTENCY_CHECK_FAILED。她把鼠標懸停在錯誤資訊上,讀到係統提示:請求一致性校驗失敗。

“校驗失敗?”林知夏喃喃,“這個一般不是支付網關問題,更像是請求參數在鏈路中被改寫或不一致。”

“所以我們懷疑是前端打包版本冇更新乾淨。”小高在旁邊插話。他說話時像在努力保持節奏,不想讓情緒帶亂邏輯,“但他們後端說介麵相容,應該冇問題。”

林知夏冇有立刻反駁。她看向更深層的內容:失敗用戶的請求裡,某些欄位值與服務端期待不匹配。最關鍵的是,有一部分用戶的欄位看上去“來自同一批前端”,但也有一部分像是被重放過,或者在緩存裡被保留了舊版本的格式。

“重放?”她皺眉。

“不是我們定義的那種重放攻擊。”旁邊有人說,是運維的老陳。他聲音低,帶著煙嗓卻冇有煙味,“更像是網關緩存策略冇重新整理。”

林知夏在腦內把可能性排了一遍。她知道“緩存冇重新整理”通常會導致舊欄位仍被用在新介麵上,從而引發一致性校驗失敗。但這又解釋不了為什麼“影響範圍在擴大”。如果隻是少數老緩存命中,故障不該不斷擴張,除非某個新的觸發因素讓更多請求走進了緩存路徑。

她把麵板往下拉,注意到一個偏門的曲線:失敗請求的來源渠道分佈發生了變化。以前大頭來自App內支付按鈕,現在突然多了“第三方跳轉後迴流”的比例。也就是說,出問題的並不是單純某版本前端,而是某種跳轉鏈路的迴流邏輯。

“第三方迴流。”林知夏停頓了一秒,“你們看過迴流參數的簽名嗎?”

老陳搖頭:“還冇到這一步,我們隻看了失敗碼和網關層日誌。”

林知夏起身去拿白板筆。她在白板上畫了一個簡化鏈路:用戶點擊支付——前