Transcription
Несколько дней назад чуть ли не весь интернет упал примерно на 6 часов. И это ощутили во всём мире, потому что упали сервера Cloud Flare, а вместе с ними и огромное количество сайтов. Но почему половина сайтов интернета упали вслед за Cloud Flare? И как всего одна строчка кода привела к такому масштабному фейлу? Давайте разбираться.
"Бать, нормально?" "А, о'кей." Сначала вопрос. Что такое Cloud Flare? По сути, это реверсивный прокси. Принцип его работы заключается в том, что он выступает посредником между сервером сайта и пользователями, то есть своего рода контрольно-пропускной пункт. Cloud Flare прогоняет через себя абсолютно весь трафик. При этом там стоят жёсткие фильтры, и нежелательный трафик тупо не доходит до серверов сайта. Сюда относятся боты, нейросетевые краулеры, HTTP флут и весь такой мусор.
В первую очередь это нужно для того, чтобы защитить сайт от DDoS атаки. Иначе, если серверу придётся обрабатывать все такие вот левые запросы, то тут никаких мощностей не хватит, и рано или поздно сервер упадёт. Приведу простой пример, чтобы было понятнее. На сайт по продаже выпечки каждый день заходит 100 человек. Бюджетный сервер этого сайта справляется нормально с такой нагрузкой. Но вот однажды, скажем, конкуренты решили помешать человеку вести бизнес и заказали на его сайт "доставку". В неожиданный момент на сайт падают уже тысячи, даже десятки и, может, даже сотни тысяч запросов. Вот только это запросы не от реальных людей. Большая часть из них вообще из каких-то левых стран. И в таком случае почти сразу бедный сервер не выдержит и упадёт. А настоящие люди, которые будут пытаться зайти на сайт, чтобы заказать свежую выпечку, не смогут на него попасть. Как результат, бизнес пострадает, продажи упадут. Короче, press to pay respect.
И даже если вы попробуете поставить супермощный сервер, это всё равно вас не спасёт. Хотя бы потому, что купить 1000 левых прокси сейчас на соответствующем рынке стоит меньше доллара, а значит, организовать атаку со 100 000 разных IP-адресов обойдётся даже дешевле 100 баксов. Просто напомню, что положить бюджетный сервер можно и при помощи всего пары тройки тысяч таких прокси. Вот такая математика. И именно по этой причине большинство владельцев сайтов пользуются услугами Cloud Flare, у которого буквально за копейки можно взять защиту от DDoS, причём сразу с поддержкой уровня L7.
Но давайте не будем вдуваться в технические дебри. Главное, чтобы вы понимали, почему упала половина интернета. Потому что отказал посредник. Сервер Cloud Flare перестал отвечать. И даже если сами сервера сайтов прекрасно работали, это не играло абсолютно никакой роли, так как запросы шли через Cloud Flare.
И вот мы подошли ко второму вопросу: а почему упал Cloud Flare? О'кей, вы будете смеяться, но проблема оказалась всего в одной строчке кода криво написанного кода. И с этим уже даже никто не спорит. Кстати, вот этот код. И он написан на языке Rust. Я тоже пишу на языке Rust, так что я прекрасно понимаю, что тут происходит и что тут не так. Видите вызов метода `unwrap` в конце? Так вот, это что-то типа исключений в Rust. В этом конкретном случае это необработанное исключение, а произошло оно потому, что метод `append_with_names`, судя по всему, возвращает перечисление `Result`, который в Rust является по сути заменой типа `null`. И оно может принимать одно из двух значений: `Ok` или же `Err`, то есть ошибка. Если на него вызвать `unwrap`, то в случае с `Err` код запаникует. Проще говоря, программа крашнется. Можете почитать подробнее, почему так произошло в блоге Cloud Flare. Они уже об этом написали большой подробный отчёт.
Я же хочу обратить ваше внимание на то, что тут проблема не в языке Rust. Он тут совсем не виноват. Любой Rust-программист, даже новичок, обязательно обратит внимание на `unwrap` в коде, особенно если это касается кода сервера, который может вот так упасть и вообще положить сайт. Смотрите, так как фьючер тут в программе передаётся по мутабельной ссылке, а сама функция возвращает пустой кортеж, можно сделать предположение, что код писал C++ программист. Причём, скорее всего, он переписывал код с плюсов в Rust буквально один в один, строчка в строчку, не учитывая правила, стилистику и, в конце концов, идиоматику языка. По этой теме, кстати, на GitHub есть целый репозиторий, который так и называется: Idiomatic Rust. Советую посмотреть.
То есть в идеале они могли бы переписать этот код, ну, скажем, вот так. То есть не вызывать `unwrap`, а вместо этого обрабатывать эту ошибку. То есть делать, ну, например. Хотя тут нужно понимать такой момент, что `unwrap` сам по себе не является причиной ошибки. Он лишь показал, что пришло `Err` вместо `Ok`. А вот почему пришло `Err`, то есть ошибка, вот это уже настоящая причина. Короче, такие пироги. Я хотел вам рассказать, как это работает и почему так произошло. А ещё рассмотреть такой вот интереснейший случай, когда, грубо говоря, всего одна строчка кода положила половину интернета. Ну а вы пишите в комментариях свои мысли по этому поводу. И, конечно же, ставьте свои царские лайки. Подписывайтесь на канал и не забывайте врубать колокольчик уведомлений. Удачи. И всегда помните: обрабатывайте ошибки в коде.