打開網(wǎng)易新聞 查看精彩圖片

只因?yàn)槁懥艘恍写a,macOS 錄屏工具 Screen Studio 的開發(fā)者 Adam Pietrasiak 意外燒掉了 8000 美元的流量費(fèi),連帶著還讓部分用戶斷了網(wǎng)。一個(gè)看起來微不足道的自動(dòng)更新改動(dòng),最后變成了一場技術(shù)災(zāi)難。這不僅是一場“翻車事故”,也給所有開發(fā)者敲響了警鐘:凡是跟網(wǎng)絡(luò)、成本沾邊的代碼,真的一點(diǎn)都馬虎不得。

這篇名為《One line of code that did cost $8,000》的文章雖然寫于 2023 年,最近卻在 Hacker News 上被翻了出來,再次引發(fā)開發(fā)者圈熱議。

來源:https://pietrasiak.com/one-line-of-code-that-did-cost-dollar8000

作者 | Adam Pietrasiak

編譯 | 屠敏

出品 | CSDN(ID:CSDNnews)

由于一個(gè) Bug,macOS 錄屏應(yīng)用 Screen Studio 的自動(dòng)更新機(jī)制出了問題:每隔 5 分鐘就會(huì)讓每位用戶重復(fù)下載一次更新文件。這個(gè)更新包有 250MB,大量重復(fù)下載導(dǎo)致請求次數(shù)飆升至 900 萬次,最終生成了超過 2PB(約 200 萬 GB)的 Google Cloud 流量。

當(dāng)時(shí)的流量波動(dòng)如下圖所示,雖然這個(gè)截圖本身看起來沒什么大不了,但背后的流量規(guī)模可不容小覷:在一個(gè)多月的時(shí)間里,Screen Studio 的服務(wù)端持續(xù)跑出至少 100 Mib/s 的帶寬,有時(shí)甚至逼近 1 GiB/s——而且是每一秒都在大規(guī)模傳輸數(shù)據(jù)。

打開網(wǎng)易新聞 查看精彩圖片

這個(gè) Bug 簡單得令人痛心,甚至可以說愚蠢至極。

簡單來看,Screen Studio 是一款運(yùn)行在 macOS 上的本地屏幕錄制應(yīng)用。出于常規(guī)需求,身為開發(fā)者的 Adam Pietrasiak 為它設(shè)計(jì)了一個(gè)自動(dòng)更新機(jī)制,讓用戶可以方便地獲取最新版本。

更新邏輯其實(shí)也很簡單:應(yīng)用會(huì)每五分鐘檢查一次更新,或者在用戶啟動(dòng)時(shí)主動(dòng)檢查。一旦檢測到有新版本,就會(huì)下載更新文件,并暫停五分鐘一輪的檢查循環(huán),直到用戶完成安裝并重啟應(yīng)用為止。

打開網(wǎng)易新聞 查看精彩圖片

悲劇性的重構(gòu)

最初,Screen Studio 的自動(dòng)更新機(jī)制還有個(gè)小問題:一旦檢測到新版本,應(yīng)用會(huì)立刻彈窗提醒用戶更新。但這在用戶錄屏?xí)r出現(xiàn)彈窗將會(huì)非常擾人——畢竟誰也不希望錄到一半被窗口打斷。

為了改善這一體驗(yàn),Adam Pietrasiak 決定對更新邏輯進(jìn)行了重構(gòu)。不過,就是在這次重構(gòu)中,出了個(gè)代價(jià)慘重的疏忽:他漏掉了一行關(guān)鍵代碼——在更新文件已經(jīng)下載后,應(yīng)該停止后續(xù)的定時(shí)檢查。

忘記這行代碼的后果就是:應(yīng)用每五分鐘就會(huì)重新下載一次同一個(gè) 250MB 的更新包。

打開網(wǎng)易新聞 查看精彩圖片

悲劇性的運(yùn)行環(huán)境:后臺運(yùn)行數(shù)周

問題在于,事實(shí)證明有成千上萬的用戶把 Screen Studio 這款應(yīng)用長期掛在后臺運(yùn)行,即使他們并沒有主動(dòng)使用。

這間接地導(dǎo)致 Bug 的影響被大大放大——這些客戶端每隔五分鐘就自動(dòng)下載一次 250MB 的更新文件,而且是持續(xù)了好幾個(gè)星期。

來做個(gè)簡單的計(jì)算:

  • 每五分鐘一次的頻率,一天大約會(huì)執(zhí)行 288 次下載。

  • 每個(gè)更新文件約為 250MB,也就是每天每位用戶產(chǎn)生約 72GB 的下載量。

  • 這一 bug 持續(xù)了一個(gè)多月,而開發(fā)者 Adam Pietrasiak 完全沒有察覺到。

  • 該應(yīng)用大約有一千個(gè)這樣的客戶端實(shí)例始終在后臺運(yùn)行。

  • 250MB × 288 次/天 × 30 天 × 1000 用戶

打開網(wǎng)易新聞 查看精彩圖片

  • 換算之后就是——2,000,000GB

  • 或 2,000 TB

  • 或 2PB 的流量


打開網(wǎng)易新聞 查看精彩圖片
一連串糟糕的錯(cuò)誤

雪上加霜的是,Adam Pietrasiak 當(dāng)時(shí)并沒有在 Google Cloud 上設(shè)置任何流量或賬單預(yù)警機(jī)制——畢竟,過去每月的賬單從未超過 300 美元,也就沒太放在心上。

而流量監(jiān)控呢?也沒人主動(dòng)去看,因?yàn)椤耙郧皬膩頉]出過問題”。

那這場事故最后是怎么被發(fā)現(xiàn)的呢?并不是通過技術(shù)手段,而是因?yàn)?Adam Pietrasiak 的信用卡因?yàn)槌^了其設(shè)定的限額而被銀行拒付了(所幸他事先設(shè)了限額,否則后果可能更慘)。

打開網(wǎng)易新聞 查看精彩圖片


打開網(wǎng)易新聞 查看精彩圖片
對用戶的影響

這不僅對我們來說是場災(zāi)難,對一些用戶來說更是嚴(yán)重的問題。

對于一部分用戶來說,它甚至成了現(xiàn)實(shí)生活中的麻煩:由于更新文件是從用戶設(shè)備端發(fā)起的下載,超大流量實(shí)際上是“從他們自己的網(wǎng)絡(luò)里跑出去”的。

有位用戶住在郊區(qū),結(jié)果因?yàn)楫惓8哳l的網(wǎng)絡(luò)使用,被當(dāng)?shù)氐倪\(yùn)營商直接斷了網(wǎng),甚至取消了服務(wù)合同——更糟糕的是,那一片區(qū)域沒有別的可選網(wǎng)絡(luò)提供商。

得知此事后,Adam 表示將對事件負(fù)責(zé),并承擔(dān)由此產(chǎn)生的全部費(fèi)用。幸運(yùn)的是,那位用戶最終還是與運(yùn)營商協(xié)商解決了問題,沒有造成進(jìn)一步損失。

盡管如此,對開發(fā)者和用戶來說,這都是一次糟糕的經(jīng)歷。Adam 后來說,作為一名設(shè)計(jì)師,他一直非常在意用戶體驗(yàn)——但這次的事故,不只是糟糕體驗(yàn),甚至一度對用戶造成了實(shí)際傷害。

打開網(wǎng)易新聞 查看精彩圖片

總結(jié)教訓(xùn)

基于此,Adam Pietrasiak 自己也總結(jié)了一些經(jīng)驗(yàn),也希望能給其他開發(fā)者提個(gè)醒:

  • 始終為云服務(wù)設(shè)置費(fèi)用預(yù)警;

  • 寫自動(dòng)更新邏輯時(shí)要極其小心;

  • 任何可能帶來成本的代碼都要格外謹(jǐn)慎;

  • 設(shè)計(jì)可由服務(wù)器遠(yuǎn)程觸發(fā)的特殊信號機(jī)制,比如“強(qiáng)制更新且不提示用戶”;

  • 定期檢查你的云服務(wù)狀態(tài)。

打開網(wǎng)易新聞 查看精彩圖片

最后

隨著 Adam Pietrasiak 把這次事故分享出來,也引發(fā)了不少開發(fā)者的討論。

有網(wǎng)友指出,這次事件的損失可能遠(yuǎn)不止賬單上寫的 8000 美元。比如用戶用的是流量,像移動(dòng)熱點(diǎn),很可能因此悄悄多花了不少錢,卻完全不知道是應(yīng)用的問題。

也有人認(rèn)為,像自動(dòng)更新器這種容易出問題、又特別關(guān)鍵的功能,其實(shí)沒必要硬著頭皮自己做。用個(gè)成熟、靠譜的第三方方案,反而更省事、安全。畢竟,一旦 App 出了嚴(yán)重 Bug,更新機(jī)制就成了唯一的補(bǔ)救通道,設(shè)計(jì)得不靠譜,后果可能比想象中嚴(yán)重得多。網(wǎng)友 jmull 指出,「像“每五分鐘檢查一次更新”這種設(shè)計(jì),就挺離譜的,說明他們可能根本沒認(rèn)真設(shè)計(jì)這個(gè)系統(tǒng)。」

還有開發(fā)者將其歸咎為沒有代碼審查。用戶 donatj 表示,「我一直對代碼評審非常嚴(yán)格。有一次,一個(gè)經(jīng)理隨口說我應(yīng)該多留點(diǎn)問題給 QA 處理,語氣差不多是“最壞能出什么問題?”我當(dāng)時(shí)脫口而出:“我們?nèi)紒G掉工作?!蔽覀冇肋h(yuǎn)離“因?yàn)橐恍性愀獾拇a丟掉工作”只差一步。我抓到初級甚至資深開發(fā)者寫出可能泄露用戶隱私信息(PII)的代碼的次數(shù),簡直數(shù)不清。在大多數(shù)系統(tǒng)中,一不小心就可能惹上法律麻煩,這實(shí)在太容易了。」

這次事件雖然是個(gè)意外,但對很多人來說,也是一個(gè)值得認(rèn)真思考的教訓(xùn)。無論是系統(tǒng)設(shè)計(jì)、代碼審核,還是日常監(jiān)控和應(yīng)急預(yù)案,做得細(xì)一點(diǎn)、穩(wěn)一點(diǎn),總歸是有好處的。

打開網(wǎng)易新聞 查看精彩圖片