Интернет-магазин под нагрузкой — метрики качества веб-кластера

    Написан, перенесен на хостинг и запущен большой интернет-магазин. Креативные идеи — выстроились в очередь на реализацию. Однако Вас очень беспокоят вопросы обеспечения стабильности работы решения и удовлетворенность покупателей — клиенты, даже в случае пиков нагрузки, не должны дожидаться перед белым экраном загрузки страницы по 30 секунд и получать сообщение типа «К сожалению, система перегружена или возникла внутренняя ошибка. Налейте себе кофе и попробуйте обратиться еще раз».



    Определим простую и эффективную стратегию достижения и поддержки высокого уровня качества обслуживания посетителей интернет-магазина — с использованием бесплатных инструментов анализа и мониторинга.
    Статья будет полезна как для проектов на базе Битрикс (в т.ч. веб-кластерных), так и для других решений на nginx+apache-php/php-fpm+MySQL.

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

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

    Что нужно фиксировать

    Прежде всего нужно модифицировать стандартный формат логов nginx, apache, php-fpm — и добавить туда описанные ниже ключевые показатели производительности. Важно фиксировать по каждому хиту следующие данные (кроме стандартных данных, таких как URL запроса, код ответа и т.п.):

    Время выполнения запроса

    Для nginx это "$request_time". При двухуровневой конфигурации nginx+apache или nginx+php-fpm полезно зафиксировать в логе nginx также "$upstream_response_time".

    Для apache это "%D".

    Для php-fpm это "%{mili}d".

    Пиковое использование памяти при обработке запроса

    Если Вы используете 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"


    Оффлайн анализ логов

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

    Распространенные типы ошибок

    В случае ошибок в PHP коде или самом ядре языка, прекомпиляторе (Segmentation Fault) или в операционной системе как правило отдается статус 500 (Internal Server Error). В этом случае, в большинстве веб-проектов, посетителю показывается страница о регламентных работах (или, если не настроить — техническое сообщение об ошибке :-) ).
    Во время перегрузки apache или php-fpm в двухуровневой конфигурации: долгие запросы к БД или в коде идет обращение к внешнему сокету, или число воркеров на бэкэнде (число процессов apache/php-fpm) не соответствует реальной нагрузке — фронтэнд (nginx) зафиксирует в своих логах превышенное время отдачи страницы бекэндом или ошибки 502 Bad Gateway, 504 Gateway Timeout. В этом случае, если не используется балансировщик нагрузки, посетителю как правило показывается страница о регламентных работах. При использовании балансировщика (например upstream в nginx) — время отдачи страницы клиенту просто увеличится (что также будет зафиксировано в логах).
    При превышении скриптом PHP памяти в лог попадет ошибка 500 (Internal Server Error).

    Иногда, правда, нужно сознательно из приложения отдать код ошибки — в этом случае можно просто исключить эти записи из лога при обработке.

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

    Полезные отчеты по логам

    Теперь можно проанализировать что происходило с обслуживанием наших покупателей за сутки. Внимание — приведенные ниже листинги скриптов адаптированы под конкретный формат лог-файлов, поэтому их скорее всего нужно будет адаптировать к Вашему проекту, что не должно вызвать сложностей.

    Гистограмма HTTP-ответов на фронтэнде и бэкэнде

    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%

    #!/bin/bash

    TOTAL=`cat /var/log/nginx.access.log | wc -l`

    echo "Total hits:" $TOTAL

    cat /var/log/nginx.access.log | awk '{ hits[$14]++; } \
    END {for (z in hits) {printf("%6s: %8s,%6.2f% ",z,hits[z],hits[z]/total*100);{s="";a=0;while(a++<int(hits[z]/total*100)) s=s"*";print s} } }'\
    total="$TOTAL" - | sort -n



    Аналогичный крошечный bash/awk скрипт можно адаптировать для логов apache/php-fpm. Мы видим, что более 99% хитов были успешны (код 200), однако было 16 ошибок, с которыми нужно разбираться разработчикам (в логах PHP) и искать способы их устранения — ведь это 16 страниц о регламентных работах :-). Наша цель — 0 кодов ответов 50x.

    Гистограмма времени выполнения страницы на фронтэнде и бэкэнде

    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%

    #!/bin/bash

    TOTAL=`cat /var/log/nginx.access.log | wc -l`

    echo "Total:" $TOTAL

    cat /var/log/nginx.access.log | awk -F'->' '{ $2=$2*1000; zone = int($2/100)*100; hits[zone]++; } \
    END {for (z in hits) {printf("%8s ms: %8s,%6.2f% ",z,hits[z],hits[z]/total*100);{s="";a=0;while(a++<int(hits[z]/total*100)) s=s"*";print s} } }' \
    total="$TOTAL" - | sort -n


    Видим, что подавляющее число запросов клиентов было обслужено со временем менее 500 ms. Однако с 398 хитами более секунды нужно основательно разбираться. Визуально удобно смотреть на столбики из звездочек (звездочка ставится если значение >1%) и учитывать только их.

    Почему страницы или сервисы могут отрабатывать единицы секунд:
    — Не используется кэширование результатов обращений в базу данных, либо само обращение в базу данных не оптимизировано.
    — Выполняется тяжелый аналитический запрос, например число заказов такого-то товара за такой-то период. В этом случае ошибки нет, такой запрос лучше исключить из анализа (например они могут идти с управляющего домена admin.myproject.ru).
    — В коде скрипта идет обращение к внешнему ресурсу, который завис (RSS лента, внешняя авторизация и т.п.).
    Общее правило тут — обращаться с подобным «рискованным» внешним ресурсам либо в отдельном потоке (cron), либо асинхронно из браузера клиента по ajax — кэшируя результаты ответа. Т.е. даже если внешний ресурс недоступен — веб-страница должна отдаться посетителю быстро, менее чем за секунду (и аккуратно догрузить части страницы).

    Гистограмма потребления скриптами памяти на бэкэнде — 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%

    #!/bin/bash

    TOTAL=`cat /var/log/php.access.log | wc -l`

    echo "Total hits:" $TOTAL

    cat /var/log/php.access.log | awk -F# '{ zone = int($11/1000)*1000; hits[zone]++; } \
    END { for (z in hits) {printf("%8s KB: %8s,%6.2f% ",z,hits[z],hits[z]/total*100);{s="";a=0;while(a++<int(hits[z]/total*100)) s=s"*";print s} } }' \
    total="$TOTAL" - | sort -n



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

    Максимальные значения

    Полезно также получить статистику по:
    — топу самых медленных страниц в сутки
    — топу самых прожорливых по памяти страниц в сутки

    #!/bin/bash

    echo "Max today slow times in php access logs: "

    cat /var/log/php.access.log | awk -F'#' '{ print $10" "$2" "$1" "$6" "$7" "$8}' | sort -nr


    Более подробно о зависаниях PHP-скриптов
    В php-fpm есть замечательная возможность логировать скрипты, выполняющиеся более N секунд и делать бэктрейс в лог:

    Mar 11 03:42:39 ec2-* [11-Mar-2012 03:42:38] [pool www] pid 26452
    Mar 11 03:42:39 ec2-* script_filename = /var/www/html/index.php
    Mar 11 03:42:39 ec2-* [0x0000000001971ea0] mysql_query() /var/www/html/bitrix/modules/main/classes/mysql/database.php:173
    Mar 11 03:42:39 ec2-* [0x00000000019718a0] Query() /var/www/html/bitrix/modules/tasks/classes/general/task.php:1145
    Mar 11 03:42:39 ec2-* [0x000000000196d078] __GetAllowedGroups() /var/www/html/bitrix/modules/tasks/classes/general/task.php:797
    Mar 11 03:42:39 ec2-* [0x000000000196cb78] GetFilter() /var/www/html/bitrix/modules/tasks/classes/general/task.php:1442
    Mar 11 03:42:39 ec2-* [0x0000000001968348] GetRootSubquery() /var/www/html/bitrix/modules/tasks/classes/general/task.php:730
    Mar 11 03:42:39 ec2-* [0x0000000001967a08] GetFilter() /var/www/html/bitrix/modules/tasks/classes/general/task.php:1473
    Mar 11 03:42:39 ec2-* [0x00000000019677b8] GetCount() /var/www/html/bitrix/modules/tasks/classes/general/task.php:1505
    Mar 11 03:42:39 ec2-* [0x0000000001964998] GetCountInt() /var/www/html/bitrix/components/bitrix/tasks.filter/component.php:105


    Мы часто пользуемся данным функционалом, т.к. он сокращает время поиска причины в разы.

    «Замыкаем» системных администраторов на разработчиков

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

    В качестве целевых критериев можно взять:

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

    Итоги

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

    P.S.

    В следующей статье мы рассмотрим способы организации он-лайн сбора и анализа ключевых показателей высоконагруженного веб-проекта с использованием pinba, nagios, awk. Иногда узнать из статистики к исходу дня что клиенты увидели 50000 страниц о регламентных работах — просто недопустимо :-) и необходимо реагировать оперативно в течении 5-10 минут. Тем не менее, ежесуточная статистика даже в этом случае — будет очень полезна. Удачи!
    1С-Битрикс
    58.63
    Company
    Share post

    Comments 103

      +1
      Приведите примеры высоконагруженных проектов на Битриксе. Насколько я знаю, таких не мало.
        +4
        Вот часть проектов: www.1c-bitrix.ru/products/cms/performance/#tab-projects-link

        Мне кажется дело не платформе, а процессе разработки и эксплуатации решения под нагрузкой. В платформе Битрикс очень много встроено средств отладки и профилирования — что существенно упрощает разработку высоконагруженных решений. Но также безусловно полезны бесплатные инструменты unix типа awk, xdebug, xhprof, pinba и отлаженный бизнес-процесс :-) с обратной связью от сисадминов к разработчикам.
        +4
        Спасибо за статью! Простые, но при этом правильные решения.
          +1
          Хорошая и полезная статья.
          Насколько мне известно, то Битрикс сам проекты не делает под заказ, с сайта предлагаете создать сайт через партнеров. Или вы только большие проекты сами делаете по знакомству или эта статья вашего партнера или как?
            +6
            Я — сотрудник 1С-Битрикс. В ходе работы мы видим множество проектов, уже запущенных, раскрученных, сделанных и на Битрикс, и на Битрикс+ZendFramework и т.п. Просто честно хочется поделиться опытом как не потерять контроль над большими проектами на PHP, неважно на какой платформе — т.к. для этого есть простые и бесплатные инструменты в unix и opensource.
              0
              >Битрикс+ZendFramework
              А кто, если не секрет, на ком стоит? То есть битрикс поверх ZF или наоборот? Или от ZF только модуль отправки писем используется?
                0
                Обе системы с достаточно низкой связанностью компонентов. Стоят как бы рядом :-). Можно брать например MVC из Битрикс, а работу с БД из ZF и т.д. Битрикс вообще легко интегрируется — например я его связывал c JBoss очередями сообщений :-)
                  0
                  При этом формат базы данных классический для зенда или инфоблоки для битрикса? Под классическим имею в виду тупо таблицу news, в которой столбцы id, title, date, text. Просто интересен момент, что делать, если формат не инфоблоковый, а через админ-панель данные менять всё-таки нужно.
                    0
                    Инфоблоки хороши для быстрого старта и основных деревьев — апи работы с иерархиями из коробки. Когда данных много — миллионы, десятки миллионов, проще деревья хранить в инфоблоках, а слабые сущности в отдельных таблицах, можно и в NoSQL запихнуть.

                    Каталог например в инфоблоках, а ценовые предложения, если их очень много — в кастомных таблицах.
                      +1
                      Если это кастомная таблица, можно АПИ инфоблоков битрикса к ней прицепить и отобразить в админке. Видел такое не раз в проектах. Метод есть для получения итератора: dev.1c-bitrix.ru/api_help/main/reference/cdbresult/initfromarray.php
                        0
                        Апи есть простое для построения админок для своих таблиц: dev.1c-bitrix.ru/api_help/main/general/admin.section/menu.php

                        Т.е. свои таблицы в Битрикс можно и нужно делать при необходимости. Желательно однако стараться с ними работать через CDаtabase, для улучшения отладки, трассировки, дальнейшей кластеризации — но это не жесткое ограничение.
                  +2
                  Да, битрикс не занимается разработкой сайтов, он целиком сосредоточен на разработке системы. А разработку сайтов на битриксе делают партнеры или частные разработчики.
                  Но большой респект битриксу за то, что им не пофигу как потом будут работать проекты, и занимаются вопросами и возможными проблемами.
                  Так же битрикс очень часто ругают за «тормознутость», но очень часто виной тут не оптимально настроенная конфигурация железа, кривые конфиги, нежели система.
                    0
                    Если какую-то систему ругают за то, что она одни и те же задачи на том же железе с теми же настройками выполняет медленнее чем другие, то значит что-то не так либо с системой, либо с её позиционированием.
                      0
                      Да вот никто никогда толком не ругает конструктивно. Никто никогда на одно и то же железо не ставит идентичные системы с битриксом и сам битрикс и не делает замеры.
                      Так же как правило не различают, что вообще то есть различные редакции битрикса: есть простые и легковесные, а есть «монстры», которые и «тяжелее», но и задачи решают другого уровня.
                        0
                        Я не ругаю, битрикс не видел даже. Но как-то мне кажется (сайт его смотрел всё же на предмет использования и ушел — так я заказчикам должен останусь), что у него структура модульная, а подключать неиспользуемые для данного запроса модули как-то… не рационально. А, да, там же ООП нет, а значит autoload не при делах, а выписывать все зависимости лень что ли?
                          0
                          Неиспользуемые модули не подключаются.
                          Автолоад используется.
                  –2
                  имхо, Битрикс хорошо подходит для обычных сайтов вроде корпоративного сайта фирмы, небольшого интернет-магазина или сайта визитки. Очень прост в управлении и можно быстро развернуть проект. Но для высоконагруженных проектов лучше заказывать написание своего движка, ибо в любом случае он будет быстрее, так как заточится под конкретные нужды.
                    0
                    Риски большие при написании собственного движка… Битрикс изнутри напоминает unix — набор простых и неубиваемых концепций, никаких извращенных десятиэтажных объектных конструкций, доступным избранным умам. Поэтому простой или сложный проект делается на Битриксе — неважно, куда не ткни, система раскладывается на простые кубики, покрытые изнутри инструментами профилирования и отладки. Лично мне спокойнее если исходники просты и в них легко разобраться, чем с красными глазами разбирать объектые простыми Symfony ;-)
                      +1
                      Я бы не сказал что все так просто в Битриксе. Особенно радовало обильное использование глобальных переменных, что делает отладку и обнаружение зависимостей практически нереальной задачей
                        +1
                        Если все глобальные переменные и PHP ассоциативные массивы завернуть в объекты — производительность серьезно снизится. PHP это же не C++. ZendFramework вообще над многими PHP функциями навернул трехэтажные объекты — стало красивее, но тормозит то как :-)
                          +1
                          > Если все глобальные переменные и PHP ассоциативные массивы завернуть в объекты — производительность серьезно снизится

                          Да ладно? А мужики-то и не знают… В 5.4, кстати, register_globals дропнули. Битрикс это переживет? А про оптимизаторы байт-кода тоже, наверно, еще никто не рассказал? Про lazy load я даже говорить не буду, для «битрикс-программистов» это черная магия
                            +2
                            Настоящие мужики УВАЖАЮТ разработчиков, поддерживающих и успешно развивающих систему 10 лет, а «мужики» я смотрю поначитались changelogs, оглавлений до половины в книгах GoF, философских трактатов Мартина Фаулера и море по колено :-) Вспомните еще позднее статическое связывание :-) Я видел такое количество объектно-дизориентированных проектов, написанных «мужиками», уволившимся т.к. не могут более года поддерживать свои творения, что вспоминать страшно. А поддерживать такие проекты (выплачивать алименты за безрассудство) приходится еще много и много лет :-)
                              +1
                              Если по сути — отсутствие register_globals Битрикс прекрасно переживет.
                              • UFO just landed and posted this here
                                  0
                                  Спасибо, кэп!!! Прошу прощения, табличка «Sarcasm» в ремонте просто, затаскалась уже
                                  • UFO just landed and posted this here
                                      0
                                      Прямо какой-то IT-эксгибиоционизм
                                    0
                                    Только не $_GET, а $HTTP_GET_VARS. $_GET появилась уже после 4.0.
                                  +2
                                  Кстати объектная модель с подходом 1 класс — 1 файл позволяет делать очень интересные вещи, как-то сбор всех ИСПОЛЬЗУЕМЫХ классов в 1 файл, который 1 раз подключается, да ещё и в добавок кешируется APC кешем, что в итоге дает очень приличную скорость.
                                    0
                                    Не спорю, иногда объекты нужны. Но почему же никому не приходит в голову переписать linux на С++? Правильно — накладные расходы. Аналогично в движке Битрикс — лишние объекты, интерфейсы, иерархии на низком уровне ядра повредят производительности. Однако можно при необходимости ООПировать на уровне компонентов Битрикс сколько угодно, особенно при реализации сложной и медленной бизнес-логики. Хоть Message Queues юзать :-)
                                      0
                                      > Но почему же никому не приходит в голову переписать linux на С++? Правильно — накладные расходы

                                      А почему никому не приходит в голову «переписать linux» (эту фразу я даже в книжечку запишу) на додиезе? Правильно — дебилов нету. Какие накладные расходы??? Вы о чем? Чистый Си и плюсы — это разные языки, переписывание ядра с Си на любом другом языке не даст никакого профита, даже если «накладных расходов» в принципе не будет
                                        0
                                        Разные языки? Да один вырос из другого и перетянул в себя кучу костылей и добавил кучу проблем :-) Я про инструмент подходящий — на PHP городить объектные иерархии считаю идитоизмом :-)
                                          0
                                          Мне кажется, что мы с вами в разных реальностях существуем. Ну да ладно, вопрос по существу: на каком языке «городить объектные иерархии» не есть идиотизм?
                                            0
                                            ООП это методика управления сложностью. Когда становится «сложно» без объектов — их и применяют. Возьмем Java — почти все выражено на ООП и все просто безобразно тормозит. Для банковских систем со сложной бизнес-логикой и т.п., где на функциях все запутается до неузнаваемости — объекты, интерфейсы, паттерны лично я использую. Для быстрых системных задач, движков — по минимуму. Беда случается, когда люди не понимая причин появления ООП начинают им пользоваться направо и налево… везде :-) Чувство меры приобретается с опытом… поддержки чужого г… нокода.
                                              0
                                              Каждый раз когда я вижу, чужой «г… нокод» на PHP — он, почему-то, оказывается в лучшем случае процедурным. В идеальном — с вкраплениями ООП в качестве неймспейсов/префиксов. Но с активным использованием глобальных переменных в разных файлах, и даже внутри классов — 100%.

                                              Почему-то меня первым делом тянет выделить этот код хотя бы в функцию, а если две функции использующие одни и те же глобальные переменные, то в класс, которому они передаются в конструкторе. Слава богу, на практике глобальные переменные инициализируются всё же в одном месте и по ходу не меняются — исключение wordpress и drupal (насчёт последнего 100% не уверен, давно не работал с ним, а wordpress запомнился). Код bitrix не смотрел.
                                                0
                                                Если честно, PHP у профессиональных программистов является вторым или третьим языком. Нельзя начинать свою карьеру с PHP — развратишься :-)
                                            0
                                            > Разные языки? Да один вырос из другого и перетянул в себя кучу костылей и добавил кучу проблем

                                            Вы вот только не говорите это больше никому, могут зашибить ненароком
                                            0
                                            А какая собственно разница если в итоге и С и С++ компилируются в оптимизированный машинный код, в котором уже нет такого понятия как ООП и т.д
                                              0
                                              Вот после этого комментария дискуссию можно закрывать, по-моему. Ни добавить, ни убавить.
                                                0
                                                А в чем дело. Чем отличается вызов обычной ф-ции от метода класса? Разве что дополнительным указателем this на стеке
                                    +2
                                    > Битрикс изнутри напоминает unix

                                    Хорошо, что Деннис Ритчи вас уже не услышит. Битрикс изнутри напоминает свалку говнокода. Как вообще можно сравнивать классическую строгость Unix-а и эту поделку инвалидов от программирования?

                                    Статья в принципе ни о чем, если проект работает под высокой нагрузкой и простои критичны, то пользователь в принципе никогда не должен увидеть 500/502 А для этого надо принимать превентивные меры и использовать realtime-мониторинг. И оптимизировать, в первую очередь, приложение. Анализ логов хорош уже постфактум, при разборе полетов.
                                      +3
                                      Надо же с чего-то начинать. Уж лучше узнать об ошибках постфактум, при регламентной проверке, чем вообще о них не узнать и только удивляться, почему народ перестаёт заходить.

                                      Лично мне статья полезна была. Даже не столько конкретными решениями, сколько постановкой задачи. Скрипты на любом языке можно написать и это относительно просто, а вот что они должны делать сформулировать сложно для тех, кто в первый раз с подобными задачами сталкивается и толком даже не понимает, что гуглить-то. Вот вы «написали realtime мониторинг» — уже есть отправная точка. И даже ощущение, что к этому можно отнести мой скрипт на python, который по хрону каждую минуту вызывает ping -c 1 example.com, а в случае проблем (exit code >0) вызывает notify-send "Error" "Something wrong with ping of example.com"
                                        +1
                                        > И даже ощущение, что к этому можно отнести мой скрипт на python, который по хрону каждую минуту вызывает ping -c 1 example.com, а в случае проблем (exit code >0) вызывает notify-send «Error» «Something wrong with ping of example.com»

                                        Есть ощущение, что питон здесь лишний :)
                                          0
                                          Есть подозрение, что в рамки хрона это не запихнуть, нужно писать скрипт. А на чём его писать дело десятое. Но. Я могу понять скобки (хоть фигурные, хоть круглые), я могу понять отступы, я даже могу понять ключевые слова, но вот переворачивание ключевых слов мой мозг отказывается воспринимать. Я твержу себе, что FI этот то же end в Паскале (грубо говоря), но каждый раз взгляд на нём стопорится секунд на 5.

                                          Я правильно ваш намёк понял?
                                            0
                                            Эта задача решается однострочником на баше. google:// advanced bash scripting guide
                                        0
                                        Юникс, да и С — это свалка ошибок за 30 лет и антипаттернов :-) Где вы в юниксе увидели стройность? Простота — да, а костылей — море. Сила юникса — в простоте, он понятен рядовым умам.
                                          –4
                                          Мне даже ответить вам нечего. Приходите к нам на HL++, узнаете что такое действительно высокие нагрузки и как с ними работают в мире вне битрикса.
                                            +4
                                            Одно дело конференции организовывать, другое — код писать и поддерживать :-)
                                              +1
                                              Сперва добейся? :)))
                                              Ну код тоже немножко умею писать, но до вас мне, конечно же, далеко. Я так, быдлокодер на убогом недоязычке
                                                0
                                                Писать и поддерживать даже я могу! А вот продавать то, что написал…
                                                  0
                                                  А продавать — это проблема менеджеров. Вы код хороший пишите и его по-любому купят. Далеко за примером ходить не надо, совсем недавно Сысоев очень наглядно это всем доказал.
                                                +3
                                                Простите, а вы wifi уже настроили нормально?) Или опять как всегда?
                                                  0
                                                  А «как всегда» — это как? На последней HL к нам жалоб на wi-fi не поступало
                                                    0
                                                    А жалобы по вайфаю принимали?

                                                    Извините, не удержался.
                                                      0
                                                      Принимали конечно :) Мы все жалобы принимаем и обязательно рассматриваем
                                                        +1
                                                        Да ладно. Сколько народ жалуется, что даже простого автомата пополнить счет мобильного нет. Файвай ваш уже притча во языцах.
                                                        Программный комитет иногда такие лулзы пропускает, например доклад про нагрузки от комсомолки, помните? Или фейл от гугловских. Да что я вам рассказываю.
                                                        Я к тому, что вроде и конференция хорошая, спасибо вам за нее, но вот вам взгляд со стороны.
                                                        Вам битрикс не нравится, не покупайте. Ребята стараются, респект им, зачем такие вещи писать в профильном блоге.
                                                          0
                                                          Вот автоматы, увы, не к нам :( Но мы над этим думаем.

                                                          > Программный комитет иногда такие лулзы пропускает, например доклад про нагрузки от комсомолки, помните? Или фейл от гугловских.

                                                          Помню конечно :) Но ребята из комсомолки отлично настроение подняли :)
                                                          Касательно битрикса не буду больше ничего говорить, пусть ребята стараются на здоровье… Чем бы дитя не тешилось, как говорится, лишь бы…

                                                          Большое вам спасибо за обратную связь!
                                                            0
                                                            На самом деле мы давно сотрудничаем с коллегами из Онтико :-). Вот например не очень давно совместно провели нагрузочное тестирование наших продуктов и получили отличные показатели производительности.

                                                            Не раз на хайлоаде встречал стенды с Битриксом под нагрузкой.

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

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

                                                              PS Мы проводим конференцию на новой площадке в этом году, надеюсь, что вопросов по поводу wi-fi и терминалов оплаты больше не возникнет :)
                                                                0
                                                                Обязательно будем на РИТ++. К конструктивной критике всегда открыты, я вообще отвечаю в компании за качество интеграции и внедрений. В последней версии мы внедрили в продукт большой и всеобъемлющий монитор (чеклист) качества, в котором есть и рекомендации по безопасности, стилям программирования и документирования, по тонкостям ООП и паттернам работы с БД, по юнит-тестированию, по организации и проведению нагрузочного тестирования, даже по повторению шаблонов Мартина Фаулера перед сном :-) Буду искренне благодарен за замечания и предложения по развитию стандартов качества архитектуры и кода в решениях на Битриксе.
                                                                  0
                                                                  Отлично, подходите, с большим удовольствием пообщаюсь с вами :) Я буду очень рад, если мой фидбэк поможет сделать битриксэтот мир чуть лучше :)
                                              +1
                                              Анализ логов и проактивный мониторинг — это совсем разные вещи, не нужно их смешивать. Я написал об этом в конце статьи. Оптимизировать неясно что нужно — надо сначала понять, где проблема. Может диск смонтирован криво, а вы будете приложение тюнить.
                                                0
                                                > Может диск смонтирован криво, а вы будете приложение тюнить.

                                                Все понятно, извините. Наряду с сомнительной чистоты термином «битрикс-разработчик» пора вводить еще и «битрикс-сисадмин».
                                                  +5
                                                  «Битрикс-сисадмины» спроектировали и реализовали запускаемый в коммерческую эксплуатацию 12 апреля облачный интранет-сервис Битрикс24.

                                                  Особенности архитектуры:
                                                  Amazon Web Services на полную катушку
                                                  2 ДЦ
                                                  Автомасштабирование веб-кластера от нагрузки, кластера за балансировщиками
                                                  Автоматическое переключение траффика в случае аварии и при регламентных работах
                                                  Мастер-мастер репликация, Percona Server
                                                  Снепшоты файловой системы 2 раза в сутки, бинарный бэкап MySQL XtraBackup
                                                  Используем кучу промышленных сервисов амазона: S3 — для хранения данных, ELB, CloudWatch.
                                                  Более 1500 тестов в нагиос.

                                                  А чем могут похвастаться «мужики-сисадмины»? :-)

                                                    0
                                                    Да я и слов-то таких не знаю, куда там хвастаться? :) Разве что коммитами в OpenSource-проекты, но по сравнению с вашими достижениями это совсем мелко
                                                      +2
                                                      > «Битрикс-сисадмины» спроектировали и реализовали запускаемый в коммерческую эксплуатацию 12 апреля облачный интранет-сервис Битрикс24.

                                                      Ну как бы ничего сверхественного нет, честно говоря. Где киллер-фичи? Вы какой-то софт крутой написали для этого? Ну так выложите в паблик!.. Или он намертво приколочен гвоздями к самому битриксу? Теже фейсбуковцы и баду отдали в коммьюнити свои xhprof, pinba и php-fpm, которыми вы активно пользуетесь, а у вас пороху не хватает? Или тупо не осилили принцип «одна задача — одна программа», который, к слову, и лежит в основе проектирования «классического» софта под юникс
                                                        +1
                                                        А зачем сверхъестественные фичи? Клиенты, как коммерческие так и бесплатные — должны быть довольны :-) Подумаю над темой выложить наработки — пока мы делимся опытом.
                                                          –1
                                                          > А зачем сверхъестественные фичи?

                                                          А зачем тогда такой пафос?
                                                          «Спроектировали и реализовали»
                                                          У моего друга недавно сын родился, так вот когда я захожу к ним в гости, мне примерно с теми же интонациями говорят «а наш Мишенька покакал»
                                                            0
                                                            Иногда можно обойти гору :-) Кто-то будет городить огород с DRBD, OCFS2, прокладывать кабели между ДЦ, говорить страшные слова типа «linux-ha» — а кто-то грамотно интегрирует готовые сервисы в проект и заставит их работать эффективно.
                                                              –1
                                                              > кто-то грамотно интегрирует готовые сервисы в проект и заставит их работать эффективно.

                                                              Кхм… Грамотно? Пока что все, что выходит из-под ваших перьев, напоминает извращения парализованного дошкольника в notepad. В чем грамотность-то? В чем эффективность? Это как-то измерено? Графики, методики тестирования, показания очевидцев есть? Какой я получу профит, если сейчас ломанусь заказывать проект на битриксе и размещение его в облаке?
                                                                +2
                                                                Уважаемый, вы так изощренно хамите коллегам программистам, администраторам, правда работающим в других компаниях, что начинаешь задумываться — а стоит ли отвечать на бессмысленный троллинг? :-)
                                                                  –2
                                                                  Не стоит. Хамлю я только адептам битрикса.
                                                                    +3
                                                                    Хамство не относится к технологиям и продуктам, это часть культуры или ее отсутствия. Чем выше профессиональный уровень, тем скромнее ведет себя человек :-)
                                                                      –1
                                                                      Вы меня вычислили :( Я тролль, лжец и девственник, а Битрикс — вершина инженерной мысли. Я просто завидую, Вы уж простите убогого…
                                                        +1
                                                        Извините, но хвастаться надо достижениями вроде «10000 хитов в минуту без двух ДЦ и AWS» вообще.
                                                        Лично моё маленькое достижение было около 1000-3000 посетителей в секунду. На средней VDS.
                                                          0
                                                          Забыл сказать, что ошибок 50х было 0%.
                                                      –3
                                                      «Проактивный мониторинг» это тоже какой-то битрикс-сленг, да? У вас там вроде еще «проактивная защита» имеется и даже свои собственные попугаи для измерения производительности? Кстати, откройте мне большой секрет, что означают эти волшебные цифры, именуемые, ЕМНИП, «индексом производительности»?
                                                        0
                                                        Этот индекс обратно пропорционален времени выполнения пустой страницы, с подключением ядра системы.
                                                        Т.е. показывает количество хитов в секунду.
                                                          +1
                                                          > Т.е. показывает количество хитов в секунду.

                                                          Мне это напоминает негласный девиз Java-программистов: «зачем просто, когда можно сложно?»
                                                          0
                                                          В двух словах — количество страниц, генерируемых ядром продукта за единицу времени.

                                                          Тут — подробно: dev.1c-bitrix.ru/community/blogs/howto/2450.php
                                                            –3
                                                            > Эти цифры нужны для того, чтобы помочь системному администратору найти узкое место (если такое есть)

                                                            Да, термин «Битрикс-сисадмин» определенно имеет право на жизнь
                                                      0
                                                      >разбирать объектые простыми Symfony ;-)
                                                      Перфразируйте, пожалуйста, мозг поломал.
                                                        0
                                                        Сорри. «Объектные простыни Symfony».
                                                      +3
                                                      Деньги считать пробовали? В случае нереально дикого выстрела можно и переписаться плавно, с затратами в 300%. А если нет, в любом случае железо дешевле команды с хорошим архитектором на реализацию своего магазина.
                                                      +1
                                                      сохранять в лог $upstream_response_time — как я сам не додумался?!
                                                        +3
                                                        Бывает что в логах PHP время генерации маленькое, а в логе апстримов nginx дикие превышения из-за недостаточного числа воркеров PHP. Две гистограммы nginx и PHP можно одновременно вывести и сравнить :-)
                                                        +2
                                                        Супер! Очень полезная статья для разработчиков и с нетерпением будем ждать вторую часть.
                                                        Александр, а в виртуальную машину добавите средства мониторинга и диагностики — давно ведь напрашиваются?

                                                        Про nagios слышал неоднократно, но руки не доходили. Ждемс…
                                                          +3
                                                          Лучше заббикс, он графики нативнее умеет. Но это путь к холивару.
                                                            +3
                                                            Лучше Кактус www.cacti.net :)
                                                              +1
                                                              Кактус мониторить не умеет:) Мне это в заббиксе и нравится, что и мониторинг, и графики.
                                                            0
                                                            По мне заббикс — тяжелее :-) nagios
                                                              0
                                                              Nagios без базы работает и историю availability строит по текстовому логу:) Ну да у Zabbix'а куча своих косяков. Нам пришлось даже платную поддержку заказывать.
                                                            0
                                                            Да, в виртуальную машину добавим средства оффлайн и онлайн мониторинга. Статья то на самом деле о простых вещах, о которых к сожалению постоянно забывают :-)
                                                            +3
                                                            Для профилирования и real-time мониторинга php используем Pinba. Сразу видно, где какой скрипт тупит и почему.
                                                              0
                                                              Пинба отличный инструмент, но за сутки статистику не держит же. Мы тоже используем пинбу в онлайне, отлично справляется с задачами и не тормозит.
                                                                +2
                                                                Мы ее с заббиксом подружили, было долго и тяжело, но в принципе получилось, мощно и наглядно.
                                                                  +1
                                                                  А мы для нагиоса написали плагины, получающие реал-тайм выборки из пинбы — при зависаниях высылается СМСка.
                                                                    0
                                                                    А можете рассказать, как подружили? Очень любопытно.
                                                                      +2
                                                                      Для nagios, если интересно, мы сделали так. Есть скрипты, выбирающие данные из pinba в целом или одному виртхосту:

                                                                      #!/usr/bin/php
                                                                      <?php

                                                                      require_once("pinba_mysql_connect.php");

                                                                      $hostname = $argv[1];

                                                                      $c = mysql_connect($pinba_host, $pinba_user, $pinba_pswd);
                                                                      mysql_select_db($pinba_db, $c);

                                                                      if ($hostname!='%') {

                                                                      $r = mysql_query("select req_time_total,req_count from report_by_hostname where hostname='${hostname}'");
                                                                      $row = mysql_fetch_row($r);
                                                                      $result = $row[0]/$row[1];

                                                                      } else {

                                                                      $r = mysql_query("select req_count,time_total from info");
                                                                      $row = mysql_fetch_row($r);
                                                                      $result = $row[1]/$row[0];

                                                                      }

                                                                      echo intval($result*1000);

                                                                      ?>


                                                                      Или

                                                                      #!/usr/bin/php
                                                                      <?php

                                                                      require_once("pinba_mysql_connect.php");

                                                                      $hostname = $argv[1];
                                                                      $precision = 0.05;
                                                                      $show_threshold = 0.5;

                                                                      $c = mysql_connect($pinba_host, $pinba_user, $pinba_pswd);
                                                                      mysql_select_db($pinba_db, $c);

                                                                      if ($hostname!='%') {
                                                                      $r = mysql_query("SELECT count(*) from request where hostname ='${hostname}'");
                                                                      } else {
                                                                      $r = mysql_query("SELECT count(*) from request");
                                                                      }

                                                                      $row = mysql_fetch_row($r);
                                                                      $count = $row[0];

                                                                      $precision_arg = round($precision * 100, 2);

                                                                      if ($hostname!='%') {

                                                                      $r = mysql_query("SELECT COUNT(*) as num, ROUND(req_time/".$precision_arg.", 2) * ".$precision_arg." as req_time_zone
                                                                      FROM request
                                                                      WHERE hostname='".$hostname."'
                                                                      GROUP BY ROUND(req_time/".$precision_arg.", 2)
                                                                      ORDER BY req_time_zone ASC");
                                                                      } else {

                                                                      $r = mysql_query("SELECT COUNT(*) as num, ROUND(req_time/".$precision_arg.", 2) * ".$precision_arg." as req_time_zone
                                                                      FROM request
                                                                      GROUP BY ROUND(req_time/".$precision_arg.", 2)
                                                                      ORDER BY req_time_zone ASC");

                                                                      }

                                                                      while($row = mysql_fetch_row($r)) {
                                                                      $percent = ($row[0] / $count) * 100;
                                                                      if ($percent < $show_threshold) continue;
                                                                      printf("%0.2f: %-50s (%d, %0.2f%%)\n", $row[1], str_repeat("*",$percent), $row[0], $percent);
                                                                      }

                                                                      ?>


                                                                      Есть плагин nagios, дергающий эти скрипты:

                                                                      #!/bin/bash

                                                                      AVG_VALUE=`/var/log/cp/pinba/stat_php_avg_time.php $1`

                                                                      [ -z "$AVG_VALUE" ] && exit 0

                                                                      echo "$1: avg php time: $AVG_VALUE ms|"

                                                                      /var/log/cp/pinba/stat_php_distr_graph.php $1

                                                                      [ "${AVG_VALUE/.*}" -lt 3000 ] && exit 0

                                                                      [ "${AVG_VALUE/.*}" -lt 5000 ] && exit 1

                                                                      exit 2
                                                                        0
                                                                        О, спасибо большое! Надо попробовать будет.
                                                                0
                                                                Здравствуйте! Простите за оффтопик, но когда будет выпущена адекватная система для интеграции 1С-Битрикс: Корпоративный портал (с ЗУП имеется ввиду)?
                                                                  0
                                                                  >Видно, что большинство скриптов веб-решения потребляют 6-8 МБ памяти
                                                                  Не стоит забывать, что память показываемая как используемая в PHP и реальная память которую отвел по себя рабочий процесс разные величины (порой, до 10 раз). И если судить по логам, то может сложиться ложное представление о том, что все хорошо, расход памяти небольшой, а на деле сервер давно уже ушел в своп. В общем используйте внешние системы мониторинга системы, они дают более точную картинку текущего положения вещей.

                                                                  Only users with full accounts can post comments. Log in, please.