Про книгу Майкла Нейгарда «Release it!»

Release it!

На днях дочитал замечательную книгу Майкла Нейгарда, которая в переводе называется «Release it! Проектирование и дизайн ПО для тех, кому не всё равно». В оригинале книга имеет название «Release it! Design and Deploy Production-Ready Software», и знаете, русскоязычный вольный перевод названия лучше отражает суть книги, по крайней мере развертыванию (deploy) приложений на сервере посвящена лишь одна последняя (из 18) глава.

Книга посвящена проектированию веб-приложений, в основном серверной части, но в отличие от многих других книг, в названии которых встречается слово «проектирование» здесь нет пересказа паттернов проектирования из книги Банды Четырех, хотя в данной книге есть две главы, посвященные паттернам и антипаттернам, но к объектно-ориентированному проектированию они не имеют никакого отношения.

Книга рассказывает о том, как уменьшить последствия, после того, как в вашем веб-приложении что-то пойдет не так, а что-то обязательно пойдет не так — это основной посыл книги. Невозможно заранее предусмотреть все, что может случиться с вашим приложением до его выход на рынок (в онлайн). Как бы хорошо не было протестировано приложение, тесты наверняка не учитывают одну вещь — реальную нагрузку. Нагрузочные тесты — это отдельная культура, а программисты в основном занимаются юнит-тестами и интеграционными тестами, которые должны выполняться как можно быстрее, поэтому они по определению оперируют небольшими базами данных (а то и вовсе фиктивными объектами). А что произойдет, если в базе окажется не десяток записей, а миллионы?

Неполадки будут возникать. А раз от них невозможно избавиться, нужно научиться минимизировать потери от них.

В книге описывается в первую очередь, как делать не надо, а потом уже, что нужно делать, чтобы уменьшить вероятность того, что сбой произойдет, или по крайней мере, чтобы вред от него был не таким большим, каким он мог бы быть. В основном в книге говорится о высоконагруженных системах, которыми пользуются миллионы пользователей, которые работают на многих серверах за распределителем нагрузки. Как пишет автор, он может допустить, что бывают случаи, когда можно отказаться от распределителя нагрузки, но не может для себя придумать такого примера.

Основные опасности для долговечности вашей системы — это утечки памяти и рост объемов данных. Обе эти вещи убивают систему в процессе эксплуатации. И обе практически не обнаруживаются при тестировании.

Автор приводит множество примеров, в которых даже, казалось бы, благие намерения программиста заставляли приложения или падать, или виснуть, или расходовать всю имеющуюся память, или занимать весь доступный объем жесткого диска. Причем в большинстве этих случаев во время тестирования все было хорошо, проблемы возникали под реальной, большой нагрузкой.

С одного такого крупного сбоя в системе работы одной авиакомпании и начинается книга. Честно говоря, это самая скучная глава, я уже даже начал думать, что вся книга будет такой, но после началось настолько интересное и полезное повествование, что эту главу можно простить автору.

Автор попытался упорядочить типичные ошибки, назвав их «антипаттерны стабильности», а затем предлагает несколько лекарств — «паттернов стабильности», подчеркивая, что даже если вы будете применять паттерны стабильности, то отсутствие сбоев все равно не гарантированы.

Первое, с чего начинается глава про антипаттерны — это так называемые точки интеграции, т.е. места, где различные веб-приложения должны взаимодействовать между собой.

Любой сокет, процесс, канал или удаленный вызов процедуры может зависнуть — и обязательно это сделает. Зависшим может оказаться даже обращение к базе данных, причем добиться этого можно как очевидными, так и неочевидными способами.

Усугубляет ситуацию то, что программисты часто игнорируют таймауты, ведь они тестируют код у себя на компьютере, где в большинстве случаев больших задержек быть не может, чтобы их организовать, нужно заметно потрудиться. В качестве примера автор указывает на Java, где до версии 1.5. невозможно было установить таймаут при установке соединения с помощью класса HttpURLConnection. Кстати, автор все примеры приводит на Java, но кода в книжке очень мало.

Пользователи — ужасные существа. Без них системы были бы намного более стабильными. Пользователи систем имеют особый талант к творческому разрушению. Когда система балансирует на грани катастрофы, как автомобиль на краю обрыва в боевике, некоторые пользователи напоминают садящихся на крышу чаек. И все падает вниз! Пользователи всегда делают самое худшее в самый неудобный момент.

Если вы не согласны с предыдущей цитатой, то вспомните, что вы делаете, если сайт медленно реагирует на ваши действия или долго показывает белый экран? Наверняка вы нажимаете кнопку «Обновить страницу». Поздравляю, после этого серверу придется обрабатывать не только ваш предыдущий запрос (он ведь не знает, что нажав кнопку Reload, вы уже разорвали предыдущее соединение), но и новый. А если сайт медленно работает, значит он и так по уши в работе, и может быть именно ваш последний запрос станет последним для сервера, и он умрет с ошибкой OutOfMemoryError.

Ко всему этому надо быть готовым. Как одно из решений (паттерн стабильности) автор предлагает запретить кнопку «Обновить» строить систему так, чтобы выход их строя одного приложения на сервере не давал упасть всем остальным. Лучше сразу выдать пользователю ошибку с предложением зайти позже, чем выдать ту же ошибку (а то и стек вызовов), но через несколько минут, в течение которых он будет судорожно жать на кнопку «Обновить».

Автор сетует на то, что протокол HTTP не дает узнать, находится ли данный пользователь на сайте или уже ушел, а на каждое соединение тратятся драгоценные килобайты памяти.

Хотите вывести из строя практически любое динамическое веб-приложение? Выберите на сайте внешнюю ссылку и начните ее запрашивать, не отправляя файлы cookie.

Еще одна причина отказов (возможно вызванных намеренно) — это излишнее доверие cookie, полученным от пользователя, или уверенность в том, что каждый пользователь эти самые cookie добросовестно отправляет. А ведь, например, веб-пауки могут cookie игнорировать, и тогда первый зашедший к вам на сайт такой недобросовестный паук уронит сайт. В книге приводится один такой пример, когда один разработчик решил накрутить рейтинг сайта, подсовывая паукам свежесгенерированные ссылки, которые вели на страницы, содержащие другие новые ссылки, которые вели на следующие страницы и т.д. Страницы эти не кончались, и в итоге за трафик хостеру пришлось заплатить больше 10 000 долларов.

Что произойдет, если база данных внезапно вернет пять миллионов строк вместо привычной сотни? Если ваше приложение в явном виде не ограничивает набор результатов, которое оно собирается обрабатывать, все может кончиться истощением памяти или попыткой довести до конца цикл тогда, когда пользователь уже давно потерял интерес к затянувшемуся процессу.

Да, к серверу базы данных мы слишком доверяем. Например, вы часто проверяете те же таймауты при попытке подключения к базе? А ведь часто для баз данных выделяются отдельные сервера, а значит и связь с ними может быть нестабильной.

Кроме того автор рекомендует по возможности всегда использовать ORM (object-relational mapping, объектно-реляционное отображение), которое предоставляют различные фреймворки. В первую очередь из-за того, что SQL-запросы там получаются как правило достаточно шаблонные, и для них легко создать нужный индекс. А вот с самописными SQL-запросами нужно быть осторожнее, ведь они пишутся как правило для каких-то сложных или запутанных ситуаций.

Неограниченный рост журналов регистрации приводит к тому, что в конечном счете они заполняют файловую систему.

Эта книга полезна тем, что во время ее чтения понимаешь, какие моменты упустил в своем веб-приложении. Причем вроде бы особых откровений в ней нет, все, что в ней описано, все логично, но только не на все потенциальные проблемы обращаешь внимание, пока в них не тыкнут носом.

Хотя книгу издали у нас только в сентябре 2015 года, оригинал вышел в далеком 2007 году, что по меркам веб-технологий, мягко говоря, давно, но несмотря на это, нет ощущения, что книга где-то устарела. На мой взгляд, эту книгу нужно обязательно прочитать тем, кто занимается backend-разработкой, особенно если приложения рассчитаны на большие нагрузки (какую нагрузку считать большой — вопрос философский).

PS. Вы можете подписаться на новости сайта через RSS, Группу Вконтакте или Канал в Telegram.

Пожалуйста, оцените запись

УжасноПлохоТак себеХорошоОтлично (Количество голосов: 1, средняя оценка: 5,00)
Загрузка...

Leave a comment

Subscribe without commenting