7  /  96

Интернет-магазины, высокие нагрузки

Просмотров: 3019 (Статистика ведётся с 06.02.2017)
Дата последнего изменения: 23.09.2015

Общие сведения

Достаточно сложной категорией веб-проектов являются интернет-магазины. Для разработки магазина вам необходимо разбираться в следующих ключевых сущностях Bitrix Framework, используемых при его проектировании:

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

Если в магазине представлены каталоги товаров, то модуль Торговый каталог должен быть изучен очень тщательно. Прежде всего вам необходимо спроектировать ценообразование: определиться какие типы цен будут использоваться и в каких валютах. Также необходимо заранее решить какой курс валют будет использоваться, как он будет браться и обновляться, как вы будете его округлять (если делать будете это сами). При проектировании структуры каталога товаров следует заранее продумать будут ли использоваться у вас торговые предложения, наборы и комплекты. Кроме того, модуль Торговый каталог позволяет настроить гибкие системы скидок. Даже, если возникнет ситуация, что вам требуются скидки, которых нет в Bitrix Framework, то разрешить ее можно с помощью API Bitrix Framework, написав собственные обработчики.

Модуль Интернет-магазин позволяет сделать:

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

Если ожидается, что проект будет большим, то к нагрузкам необходимо готовиться сразу. На этапе разработки следует выполнять аудит кода и оптимально использовать API Bitrix Framework, необходимо смотреть, чтобы не делались лишние запросы к базе. Кроме того, следует тщательно проектировать модели данных. Таким образом, следует использовать инфоблоки 2.0, в которых можно добавлять кастомные индексы.

Следует аккуратно работать с кешем: нельзя все кешировать. Проверяйте страницы так, чтобы они без кеша работали быстро, только потом включайте кеш, а не наоборот.

Что касается конфигурации, то настройте прекомпилятор PHP и анализируйте, что в него попадает. Проверьте в мониторе производительности, чтобы были включены все требуемые настройки PHP. Помимо этого, следует вести контроль версий и логи. Поскольку смотреть запросы - это задача программиста, то необходимо научиться понимать состояние базы данных. При работе используйте разного рода отладчики, Xdebug, XHPprof. Кроме того, рекомендуется использовать PHP-FPM для крупных проектов, потому что расходуется меньше памяти, выполняется меньше tcp/ip соединений.

Высокие нагрузки

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

Фиксация обращений в логах

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

Прежде всего нужно модифицировать стандартный формат логов NGINX, Apache, PHP-FPM и добавить туда описанные ниже ключевые показатели производительности. Кроме стандартных данных (таких как URL запроса, код ответа и т.п.), важно фиксировать по каждому хиту следующие данные:

  • Время выполнения запроса: для NGINX это "$request_time", для Apache - "%D", для PHP-FPM - "%{mili}d". Кроме того, при двухуровневой конфигурации NGINX+Apache или NGINX+PHP-FPM полезно зафиксировать в логе NGINX также "$upstream_response_time".
  • Пиковое использование памяти при обработке запроса. Если вы используете PHP-FPM, полезно сохранить в логе "%{bytes}M".
  • Код HTTP ответа. Обычно код HTTP ответа сохраняется в логах по умолчанию. Важно сохранять эту информацию, т.к. ошибки в обслуживании клиентов, как правило, имеют код ответа 40х или 50х.
  • Отдельные логи производительности и настройки логов. Иногда удобно создавать отдельные логи, сохраняющие информацию о времени отработки скрипта и пиковом использовании памяти. Можно использовать такие опции:
    • для nginx:
      log_format main '$remote_addr - $remote_user [$time_local] "$host" "$request" '
      '$status $body_bytes_sent "$http_referer" '
      '"$http_user_agent" "$http_x_forwarded_for" -> $upstream_response_time';
      
    • для apache:
      LogFormat "%t \"%r\" %>s %b child:%P time-> %D" timing
      
    • для php-fpm:
      access.format = "%R # %{HTTP_HOST}e # %{HTTP_USER_AGENT}e # %t # %m # %r # %Q%q # %s # %f # %{mili}d # %{kilo}M # 
      %{user}C+%{system}C"
      

Анализ логов

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

Для начала рассмотрим самые распространенные типы ошибок:

  • В случае ошибок в коде, прекомпиляторе (Segmentation Fault) или в операционной системе как правило отдается статус 500 (Internal Server Error). В этом случае посетителю показывается страница с сообщением о регламентных работах, либо (если не настроено) техническое сообщение об ошибке.
  • Во время перегрузки Apache или PHP-FPM в двухуровневой конфигурации (долгие запросы к БД либо в коде идет обращение к внешнему сокету, либо число процессов Apache/PHP-FPM не соответствует реальной нагрузке) front-end (NGINX) зафиксирует в своих логах превышенное время отдачи страницы back-end'ом или ошибки 502 Bad Gateway, 504 Gateway Timeout. В этом случае, если не используется балансировщик нагрузки, посетителю, как правило, показывается страница о регламентных работах. При использовании балансировщика (например, upstream в NGINX) время отдачи страницы клиенту просто увеличится (что также будет зафиксировано в логах).
  • При превышении скриптом PHP памяти в лог попадет ошибка 500 (Internal Server Error).

Теперь на примерах проанализируем, что происходило с обслуживаем клиентов магазина за сутки:

  • Допустим, имеется следующая гистограмма HTTP-ответов на front-end'е и back-end'е:

    Total hits: 265532
    200 : 264654, 99.67% 
    207 : 34, 0.01%
    302 : 830, 0.31%
    401 : 7, 0.00%
    403 : 1, 0.00%
    404 : 1, 0.00%
    500 : 16, 0.01%
    

    Мы видим, что более 99% хитов были успешны (код 200), однако было 16 ошибок, с которыми нужно разбираться разработчикам (в логах PHP) и искать способы их устранения.
  • Гистограмма времени выполнения страницы на front-end'е и back-end'е следующая:

    Total: 386664
    0 ms: 276203, 71.43%
    100 ms: 81466, 21.07% 
    200 ms: 13155, 3.40% 
    300 ms: 4282, 1.11% 
    400 ms: 2183, 0.56%
    500 ms: 1373, 0.36%
    600 ms: 968, 0.25%
    700 ms: 721, 0.19%
    800 ms: 586, 0.15%
    900 ms: 470, 0.12%
    1000 ms: 398, 0.10% 
    

    Видим, что подавляющее число запросов клиентов было обслужено со временем менее 500 ms. Однако с 398 хитами более секунды нужно основательно разбираться. Страницы или сервисы могут отрабатывать единицы секунд в следующих случаях:
    • Не используется кеширование результатов обращений в базу данных либо само обращение в базу данных не оптимизировано.
    • Выполняется тяжелый аналитический запрос, например, число заказов такого-то товара за такой-то период. В этом случае ошибки нет, такой запрос лучше исключить из анализа.
    • В коде скрипта идет обращение к внешнему ресурсу, который завис (RSS-лента, внешняя авторизация и т.п.). Общее правило в таком случае: обращаться к подобным «рискованным» внешним ресурсам либо в отдельном потоке (cron), либо асинхронно из браузера клиента по ajax, кешируя результаты ответа. Таким образом, даже если внешний ресурс недоступен, то веб-страница должна отдаться посетителю быстро, менее чем за секунду (и аккуратно догрузить части страницы).
  • Гистограмма потребления скриптами памяти на back-end'е - PHP-FPM:

    Total hits: 265562
    0 KB: 25, 0.01%
    4000 KB: 16, 0.01%
    6000 KB: 67094, 25.26%
    7000 KB: 123746, 46.60% 
    8000 KB: 61102, 23.01% 
    9000 KB: 3453, 1.30% 
    10000 KB: 1263, 0.48%
    11000 KB: 890, 0.34%
    12000 KB: 826, 0.31%
    13000 KB: 917, 0.35%
    14000 KB: 1129, 0.43%
    15000 KB: 1125, 0.42%
    16000 KB: 936, 0.35%
    17000 KB: 798, 0.30%
    18000 KB: 631, 0.24% 
    

    Видно, что большинство скриптов веб-решения потребляют 6-8 МБ памяти, что немного. Однако, нередко при разработке «в сжатые сроки» получаются скрипты, которые потребляют 500МБ или единицы гигабайт памяти, что вызывает зависание сервера и общую дестабилизацию системы. Важно анализировать данную гистограмму и ставить ТЗ разработчикам на оптимизацию объема потребляемой страницами памяти в пределах, допустим 64 МБ. Таким образом, постепенно, система будет потреблять стабильно предсказуемый объем памяти и вы будете уверены, что она внезапно не впадет «в спячку» на несколько десятков минут.

Кроме того, используя для логов соответствующие bash/awk-скрипты, полезно также получить статистику по максимальным значениям: топу самых медленных страниц в сутки и топу самых затратных по памяти страниц в сутки. А также если вы используете PHP-FPM, то можете получить более подробную информацию о зависания PHP-скриптов с помощью специальной возможности логирования скриптов, которые выполняются более N секунд.

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

  • число показов клиентам страницы о регламентных работах (т.е. число ошибок 50х): 0;
  • число хитов в публичной части, обслуженных быстрее 0.5 секунды: 100%;
  • число хитов в административном разделе (где могут выполняться «тяжелые» аналитические выборки): быстрее 10 секунд - 100%, среднее время хита в админке - 0.5 сек;
  • максимальный объем памяти, использованный скриптом: менее 128МБ, средний объем - 32МБ.

8
Курсы разработаны в компании «1С-Битрикс»

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