Яндекс — это живой организм: появляются новые сервисы, закрываются старые, переписываются имеющиеся.
Инфраструктура — не исключение, и практически каждый год мы куда-то переезжаем ради светлого будущего.
Один раз я стал источником такого переезда для многих команд в Яндексе. Мне необходимо было закопать ряд старых API и перевести всех клиентов на новые версии.
Масштаб был следующий:
- 7 HTTP API
- 15к rps входящего трафика
- 150+ задач в трекере
- 1 год работы
Тогда я познакомился, наверное, с половиной Яндекса :)
В результате кропотливой работы у одного из API осталось всего два клиента.
Клиенты передавали специальный параметр key для своей идентификации.
Я решил явно ограничить доступ на уровне nginx, чтобы случайно не появился третий клиент:
if ($args !~ "key=(AF7SR0kBOFwIA6...rgAYKvhTSvW6lg==|AAhenE0BAAAA...BoBzqNuwHcQ==)(&|$)") {
...
}Проверил на сервере. Работает. Прошел кодревью. Со спокойной совестью начал раскатывать в продакшен.
Через несколько минут приходит wwax@ и вежливо спрашивает:
Привет) Вы уже ручку закапываете? У нас очень плавно перестает отвечать ваш сервис.
Клиент стал получать примерно 1.3к rps ошибок со статусом 403. В спешке откатили. Начали разбираться.
Оказалось, когда я копировал код с сервера, то случайно скопировал перенос строки.
Клиент отсылал нормальный ключ: AAhenE0BAAAA…BoBzqNuwHcQ==
Мы ожидали на выход ключ с переносом строки:
AAhenE0BAAAA…\nBzqNuwHcQ==.
Даже на ревью две пары глаз не заметили лишнего переноса строки. Один лишний символ = инцидент. Такая вот факапочная арифметика.
Мораль: никогда не доверяйте себе на 100% и лучше лишний раз перестрахуйтесь при выкладке. Самоуверенность в любой момент может привести к печальным последствиям.