Разгружаем веб сервер15 августа 2011 11:08, комментариев нет

Интернет, Разработки

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

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

  • Изменение архитектуры программного кода веб-приложения
  • Оптимизация структуры базы данных
  • Исключение программного кода как такового, где это возможно.

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

Отказ от динамического форматирования текста

Блог содержит большое количество форматированного текста. Все элементы форматирования, если они обрабатываются сразу после чтения текста из базы данных, повторяются помногу раз. Это бессмысленная трата ресурсов. Будет более правильным хранить тексты в базе данных уже отформатированными, то есть, в виде фрагмента HTML-файла. В таком случае форматирование текста будет производиться во время его сохранения с помощью программы администрирования сайтом.

Выделение афиши в отдельное поле

Страницы сайта, отображающие списки статей, кроме заголовка, обычно показывают и небольшой фрагмент текста каждой статьи. Если текст хранится одним куском, то во время чтения текста из базы данных из него выкусывается фрагмент и только потом показывается. Делается это с помощью какого-нибудь программного когда, при чём, многократно по количеству статей на странице. Такое выкусывание является расточительной и бессмысленно повторяющейся операцией. Исключить это безобразие можно если хранить уже выкусанный предварительно форматированный фрагмент (афишу) отдельно и считывать целиком.

Одна страница — один запрос

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

Кеширование редко изменяемых данных

На моём сайте, как и в большинстве блогов, кроме основных данных показывается список меток или тегов, как они кое где называются. Этот список обновляется довольно редко и было бы, как минимум, странным читать его из базы данных каждый раз, когда браузер пользователя запрашивает страницу с сервера. Решается это методом кеширования списка меток на уровне приложения. То есть, читается список из базы данных только один раз и показывается всем пользователям. Перечитывается список меток только в случае его изменения, например, при добавлении автором блога новой метки. Соответственно, необходимо предусмотреть какой-то механизм, который будет обновлять список в кеше в случае его изменения. На примере моего сайта кеш обрабатывается специальным классом, который имеет все необходимые функции для управления кешем. Таким же образом следует поступать и со всеми другими редко изменяемыми данными.

Отказ от сложных запросов

Очевидно, что для ускорения обработки запросов к базе данных необходимо отказаться от сложных запросов, например, от конструкций типа UNION и JOIN. Как это сделать? Например, список статей блога на этом сайте показывает так же и список меток для каждой статьи. А ведь в базе данных для этого задействованы три таблицы: одна для хранения меток, другая для хранения собственно статей и третья для связи предыдущих двух. Запрос, отображающий список статей со списком меток для каждой получается неприлично запутанным и ресурсоёмким для простого чтения списка. Как же этого избежать?

Кеширование сложных связей в базе данных

Для разрешения создавшейся ситуации мы добавляем в таблицу, хранящую статьи, поле, содержащее в себе массив из пользовательского типа, хранящего имя метки и её идентификатор. Таким образом, наш заумный запрос с несколькими JOIN-ами превращается в простой SELECT к одной таблице, хранящей непосредственно статьи. А заполнением этого поля пусть займутся триггеры, срабатывающие на все три типа операций изменения данных. Мы получаем простой запрос на чтение, экономящий ресурсы и более сложную обработку данных при администрировании сайта.

Перенос ресурсоёмких операций на сторону клиента

При управлении сайтом с помощью веб-служб (а этот сайт управляется именно так) или при явном разделении сайта с программой администрирования есть смысл по возможности перенести все ресурсоёмкие операции на сторону клиента, разгрузив тем самым сервер. Такими операциями могут быть, например, программная обработка фотографий или форматирование текстов.

Отказ от динамических RSS-лент

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

Минимизация файлов стилей и отказ от SSI

Так же нужно сказать, что чем меньше количество файлов стилей на сайте, тем лучше. Не смотря на то, что они кешируются браузером, первая загрузка будет дольше да и обработка тоже. То же самое касается и включаемых на стороне сервера файлов SSI — эти действия совершенно лишние. Исполняемый файл должен быть предварительно скомпилированным и монолитным, что ускоряет его выполнение и исключает дополнительные считывания файлов на сервере. Зачем грузить сервер многократными лишними чтениями диска?

Итоги

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

Добавьте свой комментарий

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

Цитаты оформляются так: /* Цитируемый текст */.