← 倒帶五天

第 7 章:第7章:爆發

第7章:爆發

星期五早上七點,方佑廷到了公司。

他看到林哲翰已經在位子上,有點驚訝。「你幾點來的?」

「六點多。」

「你昨晚幾點走的?」

「一點。」

方佑廷推推眼鏡。「你這樣會累死。」

「把這個看完。」林哲翰把螢幕轉向他。

螢幕上是session管理的code。方佑廷坐下來,開始看。看了幾分鐘,他的眉頭皺了起來。

「這個session merge的邏輯……」他指著螢幕上的一段code,「這裡用的是session ID來判斷是不是同一個user。但session ID是client端生成的,如果兩個不同租戶的client用了相同的session ID——」

「就會被當成同一個user。」

方佑廷的臉色變了。「但session ID是UUID,重複的機率很低——」

「在低流量的時候很低。但在高並發下,如果client端沒有正確生成UUID,而是用時間戳加隨機數,那重複的機率會大幅上升。」

方佑廷沉默了。

「這個問題在demo的時候一定會被發現,」林哲翰說,「投資方會跑壓力測試。只要並發數夠高,這個問題就會出現。」

「你怎麼知道?」

林哲翰沒有回答。

方佑廷看著他,眼神裡有一種林哲翰很熟悉的東西——不是恐懼,是信任。他相信林哲翰知道他在說什麼。

「怎麼修?」方佑廷問。

「session ID不能只用client端生成的。Server端要驗證。如果發現重複的session ID,要強制重新生成。」

「但這樣會增加server的負擔——」

「用cache來存session ID的對應關係。每次client帶session ID來的時候,先查cache。如果發現這個session ID已經被另一個租戶用了,就回傳錯誤,要求client重新登入。」

方佑廷想了一下。「這樣client端要處理重新登入的邏輯——」

「我來改client端。你改server端。」

方佑廷點頭。「好。我現在開始。」

他轉回螢幕,開始敲鍵盤。

林哲翰站起來,走到陳立偉的位子。「立偉,你今天有空嗎?」

陳立偉抬頭看他。「什麼事?」

「session管理的client端需要改。方佑廷在改server端,我需要有人改client端。」

陳立偉看了他幾秒。「這不是我的模組。」

「我知道。但你是我們最好的前端工程師。」

陳立偉沉默了一下。「好。」

林哲翰把改動的需求告訴他。陳立偉聽完,點個頭,開始工作。

林哲翰回到位子上,打開Slack,看到趙品睿在工程群組裡問:「大家準備好了嗎?demo兩點開始。」

方佑廷回了:「正在做最後調整。中午前會完成。」

趙品睿回了個「好」。

林哲翰看著這個對話。在原始時間線,方佑廷沒有做最後調整。因為在原始時間線,session管理的問題沒有被發現。

但這次被發現了。而且正在被修。

他不知道這算不算改變了時間線。或者說,他已經改變了這麼多,他不知道哪一個改變才是關鍵。


上午十點,方佑廷說server端改好了。

林哲翰走過去看。Code看起來正確——server端現在會驗證session ID的唯一性,如果發現重複,會回傳401要求client重新登入。

「跑一下測試。」林哲翰說。

方佑廷跑了unit test。通過。跑了整合測試。通過。

「壓力測試呢?」

「要跑一個多小時。」

「跑。」

方佑廷設定了壓力測試的參數。林哲翰在旁邊看,確認並發數設為五百,租戶數量設為五十——比demo預期的更高。

「中午看結果。」林哲翰說。

他回到位子上,看到陳立偉正在改client端的code。螢幕上開著React的component,陳立偉正在處理401錯誤的邏輯——當server回傳401的時候,client端要自動清除session,然後導向登入頁面。

「怎麼樣?」林哲翰問。

「差不多了。再半小時。」

林哲翰點個頭。他打開自己的code repository,開始看其他模組。

但他看不進去。他的腦子裡一直在想一件事。

在原始時間線,demo出了問題。但問題不是session management——而是tenant isolation的query問題。那個問題他已經在星期四修掉了。

但現在他發現了session management的問題。這個問題在原始時間線也存在,但沒有被發現。因為在原始時間線,投資方沒有現場跑壓力測試。

那為什麼這次投資方會跑壓力測試?

因為他在星期四的排練中提到了壓力測試。他告訴趙品睿:「我們跑過壓力測試,五百並發,平均回應時間三百毫秒。」

然後趙品睿在跟投資方的溝通中,可能提到了這件事。然後投資方決定現場驗證。

他改變了時間線。但時間線也改變了他。

他修掉了一個問題,但暴露了另一個問題。

他不知道這是好事還是壞事。


中午十二點,方佑廷的壓力測試跑完了。

他看著報告,臉色很凝重。

「怎麼了?」林哲翰走過去。

「五百並發的時候,session ID重複的機率是百分之零點三。」方佑廷指著報告上的一個數字。「看起來很低,但如果同時有五百個user在線,平均會有1.5個user受到影響。」

「在demo的時候,投資方最多同時開三十個連線。」

「三十個連線,session ID重複的機率是百分之零點零一八。大約是五百分之一。」

「五百分之一。」

「對。很低,但不是零。」

林哲翰沉默了。

在原始時間線,demo的時候沒有測session management。所以這個問題沒有被發現。但這次,因為他在排練中提到了壓力測試,投資方可能會測。

五百分之一的機率。很低。但不是零。

「如果被發現了,」方佑廷慢慢地說,「會怎樣?」

林哲翰看著他。

「我是說,」方佑廷推推眼鏡,「如果demo的時候這個問題被發現了,品睿會怎麼處理?」

「他會說這是已知問題,我們正在修復。」

「然後呢?」

「然後他會找一個人來扛責任。」

方佑廷沉默了。

「這個code是你寫的。」林哲翰說。

「我知道。」

「但問題不是你的code有錯。問題是client端生成session ID的方式不夠安全。這是架構設計的問題,不是實作的問題。」

「但品睿不會這樣想。」

「我知道。」

方佑廷低下頭,看著自己的手。「哲翰哥,你覺得我會被開除嗎?」

林哲翰看著他。這個24歲的年輕人,戴著眼鏡,臉很圓,笑起來有酒窩。他看起來很年輕,像一個大學生。

在原始時間線,他回答了這個問題。他的回答是:「不會。我會保護你。」

然後他出賣了他。

「不會,」林哲翰說。「這次不會。」

方佑廷抬頭看他。「你怎麼知道?」

「因為我會確保這件事不會發生。」

方佑廷看了他幾秒,然後笑了。那個笑容裡有信任,也有一種林哲翰不知道該怎麼形容的東西——像是鬆了一口氣,又像是更深的擔憂。

「好,」方佑廷說。「我相信你。」


下午一點半,投資方的人到了。

三個人。一個合夥人,四十幾歲,穿著西裝。一個技術顧問,三十出頭,背著一個筆電包。一個分析師,看起來很年輕,手裡拿著一個平板。

趙品睿帶他們進會議室。林哲翰站在門口,看著他們坐下。

在原始時間線,他坐在會議室的角落,很少說話。趙品睿負責所有的簡報,他只在被問到的時候才回答。

但這次不一樣。

趙品睿在簡報開始之前,看了他一眼。那個眼神是什麼意思?林哲翰不確定。也許是「不要多話」。也許是「準備好」。也許是「這是你的場」。

簡報開始了。趙品睿站在投影幕前面,用他一貫的慢條斯理的語氣介紹公司、產品、市場。投資方的人聽著,偶爾點頭。

然後趙品睿說:「接下來讓我們的技術主管林哲翰來展示系統。」

林哲翰站起來,走到會議室前面。

他接過許湘芸手中的筆電,連上投影幕。螢幕上顯示系統的登入頁面。

「我先展示核心流程,」他說。「登入。」

他輸入了測試帳號。系統登入成功。

「對話。」

他點擊「對話」頁面。系統載入,顯示預設的對話紀錄。

「資料查詢。」

他輸入查詢條件。系統回傳結果。正確。

投資方的人看著螢幕。技術顧問在筆電上記錄什麼。

「好,」合夥人說,「基本功能沒問題。那tenant isolation呢?」

林哲翰看了趙品睿一眼。趙品睿的表情沒有變。

「我來展示,」林哲翰說。

他開了兩個瀏覽器,分別用A租戶和B租戶登入。然後在A租戶的瀏覽器裡,嘗試存取B租戶的資料。

系統回傳了「權限不足」的錯誤。

技術顧問點點頭。「那高並發呢?」

來了。

「我們跑過壓力測試,」林哲翰說,「五百並發,平均回應時間三百毫秒。Tenant isolation在高並發下也通過了。」

「能現場測一下嗎?」

林哲翰看了趙品睿一眼。趙品睿微微點個頭。

「可以,」林哲翰說。

他打開壓力測試的工具,設定了參數。三十個並發——跟投資方的人數一樣。五十個租戶。持續五分鐘。

「這個測試會跑五分鐘,」他說。「我現在開始。」

他按下了開始鍵。

會議室裡安靜了。所有人看著螢幕上的數據。

並發數:30。回應時間:平均280毫秒。錯誤率:0%。

一分鐘。兩分鐘。三分鐘。

數據穩定。沒有錯誤。

四分鐘。

然後螢幕上跳出了一行紅色文字。

「Session conflict detected. Tenant ID mismatch.」

會議室裡安靜了。

林哲翰看著那行紅色文字。五百分之一的機率。三十個並發。四分鐘。

被觸發了。

3900 字 •