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

Даже те, кто пока только мечтают о тысячах пользователей на своём сайте, наверняка задавались вопросом: “А сколько же пользователей мой сайт выдержит, если они зайдут одновременно?” Сразу вспоминается известное выражение “Хабраэффект” – явление отказа сайта, который оказался не готов к многочисленным переходам на него после появления в интернете ссылки.

Предположим, что сайт уже есть (или скоро будет): где же его разместить? Это должен быть классический хостинг или vps-сервер? Если vps, то какой и как его лучше настроить? А может быть вообще нет никакой разницы и проще выбрать то, что подешевле? В этой статье мы рассмотрим несколько вариантов и на практике убедимся, какой из них подойдёт лучше для нашего сайта.

Будем экспериментировать: ставить разные режимы работы сервера и замерять производительность. Нагрузку на сайт будем имитировать с помощью сервиса Loaddy.com. Там можно задать количество пользователей, нарастающий тип нагрузки и по графику будет видно, как сервер реагирует на них. Считается, что один пользователь генерирует примерно один запрос к сайту в течение 10 секунд. В качестве испытуемого сайта возьмем демонстрационный интернет-магазин на cms moguta. Он будет заполнен тестовыми «товарами», которые выводятся на главную страницу по нескольким критериям (то есть при формировании страницы идет работа с базой данных и т.п.). Так или иначе, это позволит сравнивать режимы между собой.

В качестве тестовой площадки создадим впс-сервер на ос Ubuntu. Конфигурация его будет [1 ядро, 1Gb RAM]. Будем считать, что именно такие серверы начального уровня создают в большинстве случаев для новых проектов. Тестовая версия интернет-магазина будет доступна по ip адресу http://130.193.44.219/

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

Так как в большинстве случаев вместе с vps предлагается панель управления, основные изменения настроек будем производить в ней. На vps сервере нам доступно 3 режима его работы:

  • Apache;
  • Apache в режиме CGI;
  • Nginx + php-fpm (без Апача).

Но сначала проведем испытания на хостинге:

Классический недорогой хостинг


image
Результат доступен по ссылке.

Ошибки появляются, когда количество посетителей превышает 50 чел. Хостинг перестаёт отдавать контент, при этом, если зайти в панель управления хостингом, то мы можем увидеть примерно следующее:
Ваш сайт подвергался ограничениям в течение последних 24 часов. Ресурсы процессора ограничивались для Вашего сайта. Вы достигали пределов по входным процессам (количеству одновременно запущенных PHP и CGI скриптов, заданий по расписанию и консольных сессий) 126 раз.
Что ж, понятно, хостинг есть хостинг, тем более недорогой. Можно, конечно, найти такой тариф, который будет предоставлять больше возможностей, но это всё нужно учитывать, каким-то образом узнавать точные данные ограничений, причем у каждого хостинг-провайдера.
?

VPS: Apache


Следующий на очереди – наш тестовый впс с режимом апач, который кстати предлагается по умолчанию, при установке панели управления ISP.

image

Результат доступен по ссылке.

Проблемы начинаются, когда число пользователей переваливает за 90. Если мы зайдем на наш сервер по ssh и посмотрим в этот момент на список процессов по команде top, отсортированный с помощью Shift+M (по количеству потребляемой памяти), то увидим примерно такую картину:

image

Мы видим, что процесс apache2 разросся на много дочерних и они съели всю оперативку нашего vps сервера.

Здесь нужно сделать небольшую ремарку. Дело в том, что для сервера апач теоретически существует режим, который позволяет вместо этого большого числа дочерних процессов для каждого соединения создать несколько так называемых мультитредовых, каждый из которых обслуживал бы по нескольку соединений. Называется этот режим worker, в отличие от дефолтного prefork. Но установить его непросто, в панелях типа ISP это сделать невозможно, а если озадачиться и попытаться это осуществить через ssh, то выяснится, что для этого мало выключить prefork и включить worker, еще нужна тредобезопасная версия php. А если используются модули типа Zend или IonCube, то они тоже должны быть тредобезопасными. Да и вообще, официальный сайт PHP не рекомендует устанавливать этот режим.

VPS: CGI


Давайте посмотрим, что будет при использовании режима CGI. Для этого нужно в панели управления ISP разрешить использовать PHP в режиме CGI, это делается в разделе «Учетные записи – пользователи – настройки для пользователя».

image

Результат доступен по ссылке.

Безрадостная картина получилась. Сервер отказывается выдавать контент уже при 55+ посетителях, оперативная память вся съедена процессами “php”. Далее идёт попытка восстановления работоспособности, но всё равно всё оканчивается практически 100% отказами.

VPS: Nginx + PHP-FPM


Настало время режима, в котором сервер Apache не используется вовсе, вместо него работает Nginx, а php обрабатывается модулем php-fpm. Если вы используете панель управления ISP, то необходимо разрешить этот режим для пользователя. Это также делается в разделе «Учетные записи – пользователи – настройки для пользователя». Также этот режим должен быть доступен в разделе «Настройки – Возможности – Веб-сервер(www)».

image

Результат доступен по ссылке.

То, что нужно! 100% доступности, при этом скорость загрузки и время ответа сервера находятся на приемлемых уровнях, хоть и возрастают с ростом нагрузки. Тем не менее сервер справляется!

Посмотрим на таблицу процессов в момент максимальной нагрузки на сервер:

image

Мы видим, что у нас есть еще запас по доступной оперативной памяти. А дочерние процессы php-fpm7.0 не разрастаются в больших количествах, а ограничены 5-ю экземплярами, каждый из которых обслуживает несколько потоков.

Что ж, похоже «режим-победитель» определен. Давайте выясним, сколько же одновременных посетителей сможет обслужить наш сервер в таком режиме. Но перед этим сделаем небольшой «тюнинг». Во-первых, так как apache не используется при такой работе сервера, его можно вовсе отключить. Это сделаем в панели управления ISP в разделе «Система – Службы». Во-вторых, изменим немного принцип запуска процессов php-fpm. По умолчанию он динамический. Это значит, что дочерние процессы будут висеть в памяти даже когда они не нужны. При этом память не освобождается и со временем эти процессы могут разрастись больше чем нам бы хотелось. Поэтому предлагается установить режим “ondemand” – по требованию. И задать количество дочерних процессов и время таймаута для них.

Для этого нужно будет зайти на сервер по ssh и прописать эти настройки в конфигурационный файл php. Это удобно сделать в файле для пользователя, для которого был создан домен в ISP.

Обычно он находится в /etc/php/7.0/fpm/pool.d

Итак:
sudo nano /etc/php/7.0/fpm/pool.d/www-root.conf


Видим там по умолчанию такие настройки:

[www-root]
pm = dynamic
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_children = 5
pm.max_spare_servers = 5

Чтобы заработал режим ondemand, нужно заменить это на:
pm = ondemand
pm.max_children = 5
pm.process_idle_timeout = 10s

И перезапустить php-fpm командой

sudo service php7.0-fpm restart

После этого процессы php-fpm7.0 будут создаваться по требованию (при наличии нагрузки), максимальное их количество будет =5, а после 10 секунд простоя процесс будет убиваться, освобождая оперативную память.

На всякий случай, запустим наш тест еще раз, чтобы убедиться, что вся эта самодеятельность не повлияла в худшую сторону на производительность сайта:

image

Результат доступен по ссылке.

Теперь давайте запустим Loaddy с большим количеством посетителей, чтобы понять, сколько соединений способен выдержать наш сервер:

image

Результат доступен по ссылке.

Радует то, что все запросы были обработаны, пусть и с большой задержкой, при большом их количестве в секунду. Время ответа сервера приближается к 10 секундам при количестве обращений 190+ Но давайте вспомним график режима apache, где 4 секунды ответа сервера мы получили уже при 80+ пользователях, тогда как в режиме php-fpm аналогичные лаги наблюдаются при 130 запросах, которые мы специально выделили курсором на графике выше.
А ведь это тот же самый VPS.

Таблица процессов top в конце испытания (при 200 пользователях):

image

Заметим, что после окончания тестирования, память, используемая pfp-fpm освободилась:

image

А значит наш сервер готов к новым нагрузкам.

Необходимо помнить, что сайт работает в режиме nginx+php-fpm, это означает что в работе не используется apache2 и как следствие – не используется .htaccess. Это может казаться не удобным, но это самый быстрый из возможных вариантов, а поисковики лучше ранжируют сайты, которые работают быстро.

Заключение


В завершении еще один небольшой момент: Если вы настроили на сервере всё что хотели и решили отключить панель управления ISP, или у вас кончилась на неё лицензия, учтите, что процесс “core” от неё так и останется висеть у вас на сервере. По прошествии месяцев он может разрастись, так что лучше его “убить” и удалить из автозапуска и crona.

Если хотите самостоятельно протестировать сайт с помощью Loaddy или же другими методами, он доступен по адресу http://130.193.44.219/

Комментарии (17)


  1. ainu
    24.12.2018 17:44

    Для полноты картины не хватает nginx, который стоит перед apache (и, например, отдаёт статику и медленно отдаёт ответ клиенту, в то время как процесс апача уже давно освободил память и ресурсы).


  1. tchspprt
    24.12.2018 18:12

    И вот так, легко и непринуждённо, автор прорекламировал свой интернет-магазин до релиза, бонусом подняв его рейтинг счётчиком посещений. Я.Метрика подрублена — всё хорошо! SEO выходит на новый уровень, гы.


  1. AEP
    24.12.2018 18:12

    Для полноты картины не хватает Apache + PHP-FPM.


    1. NickyX3
      26.12.2018 08:53

      Такая связка будет чуть тормознее mod_php.
      Проблема «тормозов» apache+mod_php не в mod_php, она в том, что тюнинг prefork апача сродни некоторой магии, и если идти по простому пути — то простой выход – подставить nginx перед апачем, как раз для того, чтоб медленные клиенты не держали в памяти апач долго


  1. tuxi
    24.12.2018 18:49

    Если звездный час близок, разве не логично выделкнный сервер арендовать с гигабитнвм каналом? Простенькие (дц в РФ) в 3500 в месяц стоят.


    1. andreymal
      24.12.2018 19:30

      Некоторым ИП даже 500 рублей на вдску жалко, а вы тут аж на три с половиной тыщи загнули)


  1. ntfs1984
    24.12.2018 22:05

    Простите, но о чем эта статья?

    apache+mod_php Vs apache+php-fcgi (странно кстати что автор ниасилил разницу между cgi и fcgi) Vs nginx+php-fpm?
    Ну эту разницу в скорости\удобстве настройки разве что ленивый еще не знает.

    Какой вообще нехороший человек ставит ГУЙ дабы потом заморачиваться тонкой настройкой параметров для производительности? Они кстати скорее всего будут перетерты как только ГУЙ что-либо поменяет в конфигурации, к примеру добавит новый домен.

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

    Что такое OOM и как с ним сожительствовать — автору еще предстоит узнать. Это и будет его домашнее задание.


  1. Mishiko
    24.12.2018 23:32

    Из графиков видно что автор не сумел создать достойной нагрузки, которая нагнула бы сервер. В целом непонятно что тестировалось — реальное приложение использует диск и базу (а она опять диск), что обычно и является узким местом. Какие были диски — непонятно, но создается ощущение что основная нагрузка была на чтение, когда все эффективно кэшится в ОП и диск почтни не грузится.


  1. edogs
    25.12.2018 00:15

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


    1. ntfs1984
      25.12.2018 05:04

      Не соглашусь.
      Все равно нджинксовое ядро и механизм работы со статикой быстрее чем апачевское и занимает меньше места.
      Плюс ко всему нджинкс не долбит при каждом вызове директории на поиск .htaccess (отключение обработки не отключает долбежку).
      Еще нджинкс из коробки умеет в fastcgi proxy, а это реально охрененная вещь, помогающая работать тяжелой PHP-динамике так быстро, будто это легенькая HTML-статика.
      Кроме настроек производительности, у нджинкса есть другой не менее полезный функционал, косвенно относящийся к производительности. Например ограничение количества запросов с одного IP. По моему опыту на фрилансе, скажу что половина клиентских жалоб на тормоза их сайтов с интернет-магазинами котиков — поисковые краулеры.

      И опять таки, не драматическая разница в производительности запросто превратится в драматическую при нужном количестве посетителей.
      Вот на одном из серверов которые я обслуживаю, крутится сайт с бесплатными шрифтами. На нем сейчас открыто 4330 процессов php70-fpm при том что keepalive там стоит 20 сек.


      1. alekciy
        25.12.2018 09:14

        4330? Чем смотрите? Сколько ОЗУ расходуется?


        1. ntfs1984
          26.12.2018 04:07

          ps aux | grep php-fpm

          [admin@host domains]$ cat 1001freefonts.com.log | grep '25/Dec/2018' | awk {'print $1'} | sort | uniq | wc -l
          38923
          [admin@host domains]$ cat 1001freefonts.com.log | grep '25/Dec/2018' | awk {'print $1'} |  wc -l
          1952695
          [admin@host domains]$ 


          Только за сегодня, 20 часов работы — 38923 уникальных (!!!) посетителя. Почти два миллиона запросов за 20 часов. Каков был расход памяти я вам сказать не могу, сейчас не бизнес-тайм, и на данный момент картина следующая:
          image

          Приложил картинку, а то получил сообщение в Л.С. что обманываю и нет никакого сервера :)


          1. alekciy
            26.12.2018 07:41

            Я поясню, почему приведенные цифры вызывают вопросы.
            4330 воркеров. php-fpm воркер даже в простое это где-то ~16Мб ОЗУ. Получается, что на сервере только fpm потребляет: 4330*16=~67 Гб (!) ОЗУ. У вас сервер с 128 Гб ОЗУ? Сервера с таким объемом ОЗУ лично у меня только под нагруженными сервисами аналитики.
            Касательно лога. Хотелось бы увидеть вывод:

            head -n1 1001freefonts.com.log

            Кроме того не видно, какие из запросов динамика, а какие статика. Судя по всему в логе они находятся в одной куче.


  1. alekciy
    25.12.2018 09:37

    Статья плохая. Заявленная тема раскрыта плохо, советы так же крайне сомнительные. Если кратко, то взяли три непонятных площадки в непонятной конфигурации, непонятно как нагрузили и сразу сделали выводы и дали неправильный советы (не нужно включать в режиме ondemand, задумайтесь о схеме запуска воркеров и накладных расходах связанных с этим). Характер нагрузки тоже выбран плохо. Обычная страница сейчас это один запрос порождающий за собой 1-5 AJAX запросов в течении первых 5-7 секунд. Про конфигурирование через GUI я вообще молчу…

    Вообще расчет требуемого железа делается совершенно не так. И нагрузочное так же нужно делать с пониманием того, как это работает на сервере. Не буду повторятося и просто приведу видео: Сколько выдержит мой сервер?


  1. Planet_Dust
    25.12.2018 16:52
    +1

    Называется этот режим worker, в отличие от дефолтного prefork. Но установить его непросто, в панелях типа ISP это сделать невозможно, а если озадачиться и попытаться это осуществить через ssh, то выяснится, что для этого мало выключить prefork и включить worker, еще нужна тредобезопасная версия php

    А какая версия Apache, простите, использовалась? Вместо worker давно есть event-MPM, который замечательно работает на Apache 2.4.10+, а с 2.4.24+ и подавно.

    Да и вообще, официальный сайт PHP не рекомендует устанавливать этот режим.

    Неверно, неправильно вы прочитали. Официальный сайт не рекомендует поточный режим Apache для mod_php, для FastCGI (PHP-FPM) это наилучшая практика.

    Сколько не тестил сам, Apache 2.4.24(и выше)+mod_proxy+mod_proxy_fcgi+PHP-FPM 5.6 (и выше) работают ничуть не хуже Nginx+PHP-FPM, а иногда даже стабильнее.

    Просто в апач нужно уметь, читать правильную документацию, правильно сконфигурировать и будет счастье.

    А клац-клац мейнстримовый Nginx (еще и через ISP-панель) по заметкам из ИТ-бложиков — это не показатель, уж простите.


  1. celebrate
    25.12.2018 21:46

    У вас на третьей картинке с VPS с апачом 43.8% CPU steal time. Вот это настоящая проблема, а не то, что оперативка закончилась. По своему опыту могу сказать, что steal time в районе 20% — это уже практически равносильно смерти, т.к. ничего нормально не работает.


    1. odiemius
      26.12.2018 05:01

      Ну так это же VPS, что Вы хотите. Чтоб избавиться от steal надо нормальный сервер.