2011 年,風險投資家、原 Netscape 創始人 Marc Andreesen 的一句「軟件正在吞噬世界」,警醒眾人。自此一切可編程的大門逐漸開啟。然而在百花齊放軟件驅動產品的背後,往往一個 Bug,極有可能瓦解所有。
近日,一位科技博主分享了一則早年間真實發生的一個 Bug 事件,因為一個「災難性」的軟件版本發布間接地導致了曾可以與 Reddit 匹敵的科技網站 Digg 分崩離析,最終讓這家曾經估值高達 1.6 億美元的公司被以 50 萬美元價格收購。
作為親身經歷者,軟件工程師 Will Larson 在 2018 年以《Digg's v4 launch: an optimism born of necessity.》一文,回顧了當初 Digg 公司的發展情況與個人參與的整個遭遇。萬萬沒想到的是,經歷了兩年改版重寫,再到耗時一個月的尋找 Bug,最終的問題竟是與 Python 的一個函數有關,然而彼時再想修復,似乎一切已為時已晚。藉此,通過這篇文章也想給奮戰在一線的開發者避一避坑。
背景
這家名為 Digg 的公司,成立於 2004 年,是一個以科技為主的新聞站點。與當時其他新聞網站有所不同的是,Digg 允許用戶把自己搜集的新聞和其他互聯網內容匯聚在一起進行提交,然後 Digg 通過內部算法機制將新聞抓取到網站的首頁,用於展示。
來自維基百科
這樣做有一個好處就是,Digg 將文章的篩選權利交給了用戶,可以讓他們自己篩選出最受關注和有價值的文章,然後通過訂閱方式,訂閱數量高的就會自動被推薦上首頁,由此讓更多的人看到。在時下這種新穎的做法,也讓很多用戶有了參與感,Digg 的規模也逐漸擴大。
當然,所有事情也有兩面性,也所謂「樹大招風」。
Will Larson 在 2018 年發布的博文里提到:「過去一年裡,Digg 過得異常艱難。我們的 CEO 在我加入的前一天離開了;高級工程師們鬼使神差地離開了公司,並拉走了他們剩在公司的朋友們,降低了公司的生產力;具有欺詐性的團伙規避了我們的算法,利用投票與訂閱的方式,出售我們網站頭版的訪問權,並威脅我們要及時修改算法以防止他們的濫用;我們的開發者環境配置工具壞了,沒有人知道如何修復它們,所以我們給新員工重新分配了近期離職同事的殭屍虛擬機。」
要說一家發展前景良好的公司,為何會淪落如此,一方面,必然有其內部的戰略問題,另一方面,也與外部的競爭環境有關。Will Larson 稱,受到外部的影響因素之一便是與 2011 年 Google 推出了 Panda 「反垃圾網站」算法有關。
那時,Google Panda 的主要目的是將質量低、含有垃圾內容的網頁或網站排名降低,使得高質量的內容得到應有的合理排名。
雖然Google Panda 算法本身是利好質量高的網站,但是Will Larson 表示,「當時 Digg 已經被 Google Panda 算法更新破壞了。由於該搜索更新花了一個月的時間才慢慢生效,Digg 的命運就此也發生了巨大逆轉:我們從第一個也是唯一一個盈利的月份開始下跌,一直跌到網站月流量被砍掉一半。前一個月,公司在五年的盈利道路上達到了頂峰,下一個月,公司處於自由落體狀態,即將從弱勢地位進行融資。」
為了重振旗鼓,也為了改變現狀。Digg 決定對網站的v3.5 進行重寫,將發布 Digg v4 版本。
不過時間轉瞬過去了兩年,Digg 因重重變故,導致新版本一拖再拖。然而,Digg v4 版本是該公司回歸互聯網巨頭競爭的戰場中唯一的機會,如果錯失,可能也就錯過了整個時代。後來,經過公司內部的商議,他們決定將沒有完全準備好的 Diggv4緊急上線。
重寫 Digg v4的辦公現場,來源Will Larson 博客
殊不知,這一倉促的決定也註定了其倉促的收場結局。
Python 函數的默認參數的一次失敗案例
慢慢地問題開始顯現。
彼時的上午 10 點左右,有人問研發團隊什麼時候開始切換新版本,工程師回答稱:"我們已經開始重新配置 V3 服務器了。" 不過,由於容量太小了,該團隊決定重新映像所有現有的服務器,然後在新的軟件棧中重新配置。
切換工作正式開啟,不過一些奇怪的事情發生了。切換過程中,新的網站並沒有真正地出現。運營團隊匆匆忙忙地發布了一個維護頁面,整個團隊陷入了沉思。因為,他們並沒有一個回滾計劃。然後有一個工程師給出了或許是唯一可能的選擇:繼續向前切換。
他們也的確這麼做了,一個小時後,當全部量切換完成,舊網站頁面取而代之的是 Digg v4 版本,所有人員也長舒一口氣。
不過剛高興沒多久,大家發現多數的頁面呈現無法加載的狀態。初期,該研發團隊將問題定位為 Cassandra 集群,因此他們擴大了對 memcache 的使用,作為保護 Cassandra 的一個寫通緩存。
幾個小時之後,訪客頁面沒有問題,但是已經登錄的用戶卻仍然看到報錯的頁面,如 MyNews,該頁面類似於「個人中心」,會呈現用戶與每篇文章互動的記錄以及個性化的新聞頁面。無奈之下,研發團隊將登錄用戶的默認頁面改為 TopNews,這樣使得用戶登錄之後可以使用網站。
次日,MyNews 已經徹底無法訪問,網站每隔四個小時之後就會出現故障。除此之外,還有幾十個小問題也在不斷出現。
於是,他們再次做了一個大膽的決定——從頭開始寫 MyNews 頁面。起初,該團隊以為Cassandra 的緩存擊穿了 memcache,破壞了相關功能。後來他們用 Redis 重寫了,並實施了一個分片的 Redis 集群,並成功將原來的遷移到新開發上。
遺憾的是,研發團隊還是需要每隔四個小時就手動啟動每個進程。
簡單來看,相當於問題的根源還是沒有找到,只是用了一種麻煩的替代方案來短暫支持。沒想到的是,這個 Bug 耗費了該團隊一個月的時間來追蹤。
好在最終還是發現了問題的所在。Digg 的 API 服務器是一個 Python Tornado 服務,它將 API 調用到 Python 後端層,即 Bobtail(前端是 Bobcat),其中一個最經常被訪問的端點是用來通過用戶的名字或 ID 來檢索用戶。因為它支持按名字或 ID 檢索,所以它把兩個參數的默認值都設置為空列表。
然而,Python 只在函數第一次被評估時初始化默認參數,這意味着每次調用函數時都會使用同一個列表。
在這種情況下,每次調用時,用戶的 ID 和名字都被附加到默認列表中。幾個小時後,這些列表開始在每次請求中檢索數以萬計的用戶,甚至壓垮了 memcache 集群,導致了頁面崩掉。
通過一個簡單的例子可以直接看出:
最後
事情最後的結局是,Digg 團隊修復了該漏洞,Digg v4 完全正常啟動。而距離此事過去了一周後,Digg 迎來了最後一任 CEO;一個月後,Digg 開啟第三輪裁員;一年後,Digg 公司被 Chartbeat 的母公司 Beatworks 以 50 萬美金的價格收購。
誰曾想,Digg 也是互聯網的寵兒,估值曾達到過 1.6 億美元,登上過《商業周刊》的封面,Google 也曾計劃以 2 億美元將它收入囊中。殊不知,正是這一次的失敗改版讓 Digg 迅速損失了人氣,以及內部一些管理問題,讓競品迅速超越。自此,一家創業明星公司就此隕落。
Will Larson 在文末寫道,「Digg V4 有時會被作為災難性發布的例子,隱含的教訓是我們不應該發布它。我曾經一度同意這個觀點,但現在我認為我們推出的決定是正確的。因為,我們的流量明顯下降,每個月都在損失一大筆錢。如果我們能在推出偉大的東西和糟糕的東西之間做出選擇,肯定會更傾向於推出偉大的東西,但我們卻選擇了最後一次揮棒。」
另外,他還表示,「即使是現在,我也不確定當初那樣一個有才幹的團隊是如何進行這種愚蠢的展示的。」
歸根結底,這是程序員一次技術失敗導致的慘痛教訓。也有不少網友評論道,「動態類型一時爽,代碼重構火葬場」。
參考鏈接:
https://lethain.com/digg-v4/?continueFlag=0a23bc7c424c6abc75f97cbaaa2d55ff
https://weibo.com/u/1642628345
《新程序員001-004》全面上市,對話世界級大師,報道中國IT行業創新創造!
