第2章
燈下同謀1
端發(fā)起請(qǐng)求——服務(wù)端校驗(yàn)——**轉(zhuǎn)發(fā)——支付結(jié)果回傳。她在“校驗(yàn)”處打了個(gè)圈,在“回傳”處畫(huà)了問(wèn)號(hào)。
“如果只是參數(shù)不一致,那失敗就發(fā)生在校驗(yàn)階段,不影響回流。”她說(shuō),“但你們說(shuō)失敗率在擴(kuò)大,還伴隨回流鏈路占比上升。那意味著錯(cuò)誤可能在更靠近回傳的節(jié)點(diǎn)。”
小高抬眼:“你的意思是結(jié)果回傳的請(qǐng)求也在出問(wèn)題?”
“不。”林知夏輕輕搖頭,“我想的是:回流鏈路改變后,前端構(gòu)建支付請(qǐng)求時(shí)使用了錯(cuò)誤的上下文數(shù)據(jù)。上下文本應(yīng)來(lái)自一次新的會(huì)話,但因?yàn)樘D(zhuǎn)回流沒(méi)有正確刷新,會(huì)話上下文仍是舊的。于是校驗(yàn)失敗,且由于更多回流發(fā)生,失敗范圍就會(huì)擴(kuò)張。”
她說(shuō)著把關(guān)鍵字段列出來(lái):session_id、nonce、client_timestamp。她盯住client_timestamp,覺(jué)得不對(duì)。按理說(shuō)時(shí)間戳應(yīng)該由客戶端生成并參與簽名,除非客戶端在某些情況下復(fù)用了舊的nonce。那會(huì)導(dǎo)致一致性校驗(yàn)失敗,且很難從接口兼容層面解釋。
“我需要看前端埋點(diǎn)。”她轉(zhuǎn)頭,“把這次事故中用戶的關(guān)鍵字段抓出來(lái)。”
技術(shù)組的人面面相覷。看起來(lái)大家都在等她提供“產(chǎn)品側(cè)的解釋”,但真正要的是“數(shù)據(jù)證據(jù)”。林知夏從來(lái)不喜歡空談。她迅速申請(qǐng)了查詢權(quán)限,拉取了事故時(shí)間窗口內(nèi)的樣本數(shù)據(jù)。屏幕上出現(xiàn)一張表格,行數(shù)很少,卻足夠讓人判斷:回流用戶的nonce重復(fù)率遠(yuǎn)高于常態(tài)。
“這就是了。”林知夏呼了一口氣,像把胸口的緊繃往外放,“nonce重復(fù)導(dǎo)致校驗(yàn)失敗。你們上線時(shí)有沒(méi)有改動(dòng)nonce生成邏輯,或者有沒(méi)有改過(guò)埋點(diǎn)上報(bào)時(shí)機(jī)?nonce通常和會(huì)話啟動(dòng)時(shí)機(jī)掛鉤。”
“沒(méi)有動(dòng)這塊。”有人回答,“我們版本更新主要是支付頁(yè)面的UI和一個(gè)促銷券的邏輯。”
林知夏盯著那條“促銷券邏輯”。UI改動(dòng)和促銷券邏輯都可能影響到參數(shù)構(gòu)建與會(huì)話上下文使用方式。她把可能的因果線收攏到一次促銷券請(qǐng)求的觸發(fā):如果券邏輯在支付前就觸發(fā),并且券觸發(fā)依賴某段緩存或會(huì)話狀態(tài),那么可能在回流時(shí)產(chǎn)生時(shí)機(jī)錯(cuò)位,導(dǎo)致nonce被錯(cuò)誤復(fù)用。
“促銷券模塊的代碼誰(shuí)負(fù)責(zé)?”她問(wèn)。
“周祁。”技術(shù)負(fù)責(zé)人回答。他說(shuō)到名字的時(shí)候沒(méi)有太多情緒,卻讓整個(gè)屋子像被輕輕推了一下方向。林知夏記得周祁,他是團(tuán)隊(duì)里最擅長(zhǎng)寫(xiě)“看起來(lái)沒(méi)問(wèn)題”的代碼的人。他經(jīng)常用一種溫和的口吻提出建議,但他的建議里總有一層“我已經(jīng)考慮過(guò),你不用擔(dān)心”的氣味。那氣味有時(shí)候像是自信,有時(shí)候像是在提前把鍋移走。
林知夏沒(méi)立刻追問(wèn)。她只是把數(shù)據(jù)截圖保存,然后對(duì)老陳說(shuō):“先把線上回滾策略再確認(rèn)一遍。不要只回滾版本,順便在**層加一個(gè)短暫的降級(jí)策略:對(duì)第三方回流來(lái)源的支付請(qǐng)求,強(qiáng)制要求nonce唯一校驗(yàn)通過(guò),失敗直接提示刷新支付頁(yè)。”
老陳皺眉:“那用戶體驗(yàn)會(huì)差一點(diǎn)。”
“但我們現(xiàn)在體驗(yàn)差是因?yàn)椴环€(wěn)定。”林知夏說(shuō),“如果繼續(xù)擴(kuò)大,會(huì)比體驗(yàn)差更糟糕。至少讓用戶知道自己要做什么。”
“行。”老陳點(diǎn)頭,“我去開(kāi)策略。”
她回到工位,把白板上的鏈路再畫(huà)一遍,寫(xiě)下“回流=上下文錯(cuò)位”。她在最底下寫(xiě)了一個(gè)新的詞:同謀。
這個(gè)詞是她在凌晨?jī)牲c(diǎn)半之后開(kāi)始反復(fù)浮現(xiàn)的。她并不是玄學(xué)愛(ài)好者,但她對(duì)“異常”的嗅覺(jué)像動(dòng)物一樣敏銳。她不相信純粹的事故。因?yàn)橄到y(tǒng)的錯(cuò)誤碼雖然像是隨機(jī),但時(shí)間點(diǎn)、觸發(fā)條件、字段特征,卻都像被精心擺放過(guò)。
她把“精心擺放”壓回心里。她需要先得到證據(jù)。沒(méi)有證據(jù)就不能指控任何人。可她同樣清楚:真正危險(xiǎn)的不是錯(cuò)誤本身,而是有人可能利用錯(cuò)誤制造混亂,或者掩蓋真實(shí)的操作。
群里又有人喊她:“知夏,老板在問(wèn)情況,他說(shuō)你負(fù)責(zé)產(chǎn)品側(cè)溝通。”
林知夏打開(kāi)老板的聊天窗口,輸入一段總結(jié):支付失敗率上升,定位到nonce重復(fù)導(dǎo)致一致性校驗(yàn)失
“如果只是參數(shù)不一致,那失敗就發(fā)生在校驗(yàn)階段,不影響回流。”她說(shuō),“但你們說(shuō)失敗率在擴(kuò)大,還伴隨回流鏈路占比上升。那意味著錯(cuò)誤可能在更靠近回傳的節(jié)點(diǎn)。”
小高抬眼:“你的意思是結(jié)果回傳的請(qǐng)求也在出問(wèn)題?”
“不。”林知夏輕輕搖頭,“我想的是:回流鏈路改變后,前端構(gòu)建支付請(qǐng)求時(shí)使用了錯(cuò)誤的上下文數(shù)據(jù)。上下文本應(yīng)來(lái)自一次新的會(huì)話,但因?yàn)樘D(zhuǎn)回流沒(méi)有正確刷新,會(huì)話上下文仍是舊的。于是校驗(yàn)失敗,且由于更多回流發(fā)生,失敗范圍就會(huì)擴(kuò)張。”
她說(shuō)著把關(guān)鍵字段列出來(lái):session_id、nonce、client_timestamp。她盯住client_timestamp,覺(jué)得不對(duì)。按理說(shuō)時(shí)間戳應(yīng)該由客戶端生成并參與簽名,除非客戶端在某些情況下復(fù)用了舊的nonce。那會(huì)導(dǎo)致一致性校驗(yàn)失敗,且很難從接口兼容層面解釋。
“我需要看前端埋點(diǎn)。”她轉(zhuǎn)頭,“把這次事故中用戶的關(guān)鍵字段抓出來(lái)。”
技術(shù)組的人面面相覷。看起來(lái)大家都在等她提供“產(chǎn)品側(cè)的解釋”,但真正要的是“數(shù)據(jù)證據(jù)”。林知夏從來(lái)不喜歡空談。她迅速申請(qǐng)了查詢權(quán)限,拉取了事故時(shí)間窗口內(nèi)的樣本數(shù)據(jù)。屏幕上出現(xiàn)一張表格,行數(shù)很少,卻足夠讓人判斷:回流用戶的nonce重復(fù)率遠(yuǎn)高于常態(tài)。
“這就是了。”林知夏呼了一口氣,像把胸口的緊繃往外放,“nonce重復(fù)導(dǎo)致校驗(yàn)失敗。你們上線時(shí)有沒(méi)有改動(dòng)nonce生成邏輯,或者有沒(méi)有改過(guò)埋點(diǎn)上報(bào)時(shí)機(jī)?nonce通常和會(huì)話啟動(dòng)時(shí)機(jī)掛鉤。”
“沒(méi)有動(dòng)這塊。”有人回答,“我們版本更新主要是支付頁(yè)面的UI和一個(gè)促銷券的邏輯。”
林知夏盯著那條“促銷券邏輯”。UI改動(dòng)和促銷券邏輯都可能影響到參數(shù)構(gòu)建與會(huì)話上下文使用方式。她把可能的因果線收攏到一次促銷券請(qǐng)求的觸發(fā):如果券邏輯在支付前就觸發(fā),并且券觸發(fā)依賴某段緩存或會(huì)話狀態(tài),那么可能在回流時(shí)產(chǎn)生時(shí)機(jī)錯(cuò)位,導(dǎo)致nonce被錯(cuò)誤復(fù)用。
“促銷券模塊的代碼誰(shuí)負(fù)責(zé)?”她問(wèn)。
“周祁。”技術(shù)負(fù)責(zé)人回答。他說(shuō)到名字的時(shí)候沒(méi)有太多情緒,卻讓整個(gè)屋子像被輕輕推了一下方向。林知夏記得周祁,他是團(tuán)隊(duì)里最擅長(zhǎng)寫(xiě)“看起來(lái)沒(méi)問(wèn)題”的代碼的人。他經(jīng)常用一種溫和的口吻提出建議,但他的建議里總有一層“我已經(jīng)考慮過(guò),你不用擔(dān)心”的氣味。那氣味有時(shí)候像是自信,有時(shí)候像是在提前把鍋移走。
林知夏沒(méi)立刻追問(wèn)。她只是把數(shù)據(jù)截圖保存,然后對(duì)老陳說(shuō):“先把線上回滾策略再確認(rèn)一遍。不要只回滾版本,順便在**層加一個(gè)短暫的降級(jí)策略:對(duì)第三方回流來(lái)源的支付請(qǐng)求,強(qiáng)制要求nonce唯一校驗(yàn)通過(guò),失敗直接提示刷新支付頁(yè)。”
老陳皺眉:“那用戶體驗(yàn)會(huì)差一點(diǎn)。”
“但我們現(xiàn)在體驗(yàn)差是因?yàn)椴环€(wěn)定。”林知夏說(shuō),“如果繼續(xù)擴(kuò)大,會(huì)比體驗(yàn)差更糟糕。至少讓用戶知道自己要做什么。”
“行。”老陳點(diǎn)頭,“我去開(kāi)策略。”
她回到工位,把白板上的鏈路再畫(huà)一遍,寫(xiě)下“回流=上下文錯(cuò)位”。她在最底下寫(xiě)了一個(gè)新的詞:同謀。
這個(gè)詞是她在凌晨?jī)牲c(diǎn)半之后開(kāi)始反復(fù)浮現(xiàn)的。她并不是玄學(xué)愛(ài)好者,但她對(duì)“異常”的嗅覺(jué)像動(dòng)物一樣敏銳。她不相信純粹的事故。因?yàn)橄到y(tǒng)的錯(cuò)誤碼雖然像是隨機(jī),但時(shí)間點(diǎn)、觸發(fā)條件、字段特征,卻都像被精心擺放過(guò)。
她把“精心擺放”壓回心里。她需要先得到證據(jù)。沒(méi)有證據(jù)就不能指控任何人。可她同樣清楚:真正危險(xiǎn)的不是錯(cuò)誤本身,而是有人可能利用錯(cuò)誤制造混亂,或者掩蓋真實(shí)的操作。
群里又有人喊她:“知夏,老板在問(wèn)情況,他說(shuō)你負(fù)責(zé)產(chǎn)品側(cè)溝通。”
林知夏打開(kāi)老板的聊天窗口,輸入一段總結(jié):支付失敗率上升,定位到nonce重復(fù)導(dǎo)致一致性校驗(yàn)失