Утром 22 сентября torun.ai еле двигался. Ферма автоматических браузеров, больше двух тысяч адресов за три четверти часа, запрашивала наши публичные страницы по одной, и в худшую минуту это было около трёх страниц в секунду. Сайт должен такое даже не заметить. Наш заметил: в самый загруженный промежуток больше четверти запросов выполнялись дольше тридцати секунд, и сотни посетителей сдались, не дождавшись страницы.
Не та нагрузка, что мы думали
Очевидными подозреваемыми были краулер и процессор. Ни одна версия не подтвердилась. Когда мы воспроизвели те же три страницы в секунду на копии сайта, она продержалась меньше минуты, а потом перестала завершать что-либо вообще. Загрузка процессора упала с 60 процентов до 1, а число потоков выросло с 12 до 166. Перегруженный сервер работает больше; этот ждал.
Обращение за каждым словом
Наблюдение за кеш-сервером во время одной страницы показало, чего он ждал. Одна страница отправляла ему 585 команд, и 428 из них были одним запросом и его продлением, снова и снова: таблица переводов, которая у нашего сайта пуста. Каждый переведённый текст на странице, а их на странице сотни, запрашивал её заново, и каждый запрос держал поток, пока не придёт ответ. На трёх страницах в секунду потоки закончились, и всё встало в очередь за ними.
Исправление и ограничение
Теперь эти запросы на минуту обслуживаются из памяти, по истечении заново загружаются один раз и сбрасываются на том сервере, где меняют перевод. Та же страница отправляет теперь 31 команду вместо 585. Ещё мы поставили ограничение перед формированием страниц: одновременно формируется фиксированное число страниц, короткая очередь ждёт, а всё сверх этого сразу получает «попробуйте ещё раз через минуту» вместо того, чтобы замедлять каждую страницу.
Измерено в продакшене
После релиза 23 сентября мы снова измерили работающий сайт. Медианная страница формируется за 42 миллисекунды вместо 249, а самая медленная из двадцати — за 72 миллисекунды вместо почти двух секунд. Запрос, который выполнялся 214 раз на страницу, теперь выполняется один раз.
Урок, который мы записали, простой: цифра производительности — это измерение, а не убеждение. Мы никогда не проверяли, что выдержит публичный сайт. Теперь проверили и проверим снова, прежде чем назвать цифру.