9 月 22 日上午,torun.ai 慢得幾乎動不了。一批自動化瀏覽器,在四十五分鐘內來自兩千多個位址,逐一請求我們的公開頁面,最糟的那一分鐘大約是每秒三頁。一個網站本該對此毫無感覺。我們的卻撐不住:最繁忙的時段裡,超過四分之一的請求耗時超過三十秒,數百名訪客沒等頁面出現就離開了。
不是我們以為的負載
最明顯的嫌疑是爬蟲和處理器,但兩者都站不住腳。我們在網站副本上重播同樣的每秒三頁,它撐了不到一分鐘,之後就什麼請求都完成不了。處理器使用率從 60% 降到 1%,執行緒數卻從 12 漲到 166。過載的伺服器會更忙;這台卻在等待。
每個詞都要往返一次
在單一頁面產生期間觀察快取伺服器,就看清了它在等什麼。一個頁面向它送出 585 道指令,其中 428 道是同一個查詢及其續期,反覆出現:一張對我們網站來說是空的翻譯表。頁面上每一段翻譯文字,而一個頁面有好幾百段,都要重新請求它一次,每次請求都會佔住一個執行緒,直到結果回來。每秒三頁時執行緒就耗盡了,所有請求都排在它們後面。
修正,以及一道限流
這些查詢現在每次從記憶體回傳一分鐘,過期時只重新取得一次,並在修改翻譯的那台伺服器上清除。同一個頁面現在只送出 31 道指令,而不是 585 道。我們也在頁面產生前加了一道限流:同時只產生固定數量的頁面,一個短佇列等待,超出的部分會立刻收到「請稍後再試」,而不是拖慢所有頁面。
在正式環境實測
9 月 23 日發布之後,我們重新量測了線上網站。頁面產生的中位時間是 42 毫秒,之前是 249 毫秒;每二十個裡最慢的是 72 毫秒,之前將近兩秒。每個頁面原本要執行 214 次的查詢,現在只執行一次。
我們記下的教訓很簡單:容量數字是量出來的,不是信出來的。我們從沒測過公開網站能承受多少。現在測過了,以後給出數字之前還會再測。