Грязный Стресс-Тест Nginx Против Apache

Добрый день! Недавно я заинтересовался вопросом, какие технологии можно использовать для построения информационной системы, которая бы отвечала на более-менее простые запросы клиентов, но максимально быстро и надежно.

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



Задача
Я сформулировал задачу следующим образом:
  • Клиент должен отправить запрос на сервер с некоторыми параметрами
  • Сервер должен поместить параметры в базу данных
  • Сервер должен вернуть идентификатор базы записей.

  • Клиент должен инициировать новый сеанс TCP, запросить уже созданную запись.

  • После этого сервер отмечает, что транзакция завершена.



Тесты
Изначально планировалось протестировать большое количество вариантов, а именно: собственный сервер на C++ Нгинкс + PHP nginx + собственный модуль апач + PHP Apache + специальный модуль что-то самодельное в .

NET однако, как любой уважающий себя сисадмин, я поленился и ограничился Нгинкс + PHP И апач + PHP , в надежде, что остальные эксперименты проделаю позже (или после Ваших комментариев к этой статье они не понадобятся) В качестве базы данных я использовал MySQL.

База
В таблице я сделал 3 контрольные точки: 1. Время создания записи (с точностью до миллисекунд) 2. Время завершения транзакции (с точностью до миллисекунд) 3. Время создания записи (с точностью до секунд) Контрольная точка 3 нужна для того, чтобы можно было понять, сколько записей создается в секунду.

В общей сложности база получилась примерно такой:

  
  
  
  
  
   

create table clients (id int not null auto_increment, amount double not null, hash char(32), Primary key (id)); alter table clients add cr_time char(100); alter table clients add ps_time char(100); alter table clients add column sec_time TIMESTAMP default NOW();



Инфраструктура
В качестве сервера у меня под рукой был только один из последних Aspire One, с процессором Atom, 2 ядрами, 4 потоками и установленной на нем Ubuntu 10:

root@aspire-1-laptop:/etc# cat /proc/version Linux version 2.6.32-41-generic (buildd@vernadsky) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) ) #89-Ubuntu SMP Fri Apr 27 22:22:09 UTC 2012

Подключен к домашнему роутеру (Каньон, модель за 40 баксов, года 2 назад), соединение 100 мегабит, провод. В качестве ботов для создания нагрузки я использовал следующие машины: 2 ноутбука с Core Duo (один старый Dell, другой старый Fujitsu), подключенных кабелем к одному маршрутизатору 1 ноут с i5 (новый Dell) подключенный по Wi-Fi, тоже к тому же роутеру.

Все настройки делались по инструкции в первых ссылках Google , так что ни о какой конкретной оптимизации речи не идет.

Бот
На всех ноутбуках была установлена Windows 7, поэтому мне показалось, что проще всего построить бота на C#, который в цикле создаст необходимое количество потоков и начнет считать «транзакции».

Основной код бота выглядит так:

public void beginTransaction() { while (true) { string response = this.createRecord(); string id = response.Substring(0, response.IndexOf('|')); string final = this.updateRequest(id); StringReader strReader = new StringReader(response); StringReader strReader2 = new StringReader(final); } } public void start() { for (int i = 0; i < int.Parse(this.textBox1.Text); i++) { this.richTextBox2.BeginInvoke((MethodInvoker)(() => this.richTextBox2.AppendText("thread started \n"))); Thread oThread = new Thread(new ThreadStart(beginTransaction)); oThread.Start(); while (!oThread.IsAlive) ; } }



Веб-часть
Я реализовал небольшой скрипт на PHP, который фактически делает все, что мне нужно, например:

<Эphp error_reporting(E_ALL); ini_set("display_errors", 1); mysql_pconnect('localhost','root','qwerty') or die(mysql_error()); mysql_select_db('test') or die(mysql_error()); if (isset($_REQUEST['id'])){ if (trim($_REQUEST['id'])!=''){ // echo 'ktulhu fhtagn'; $result = mysql_query('select * from clients where id = "'.

addslashes($_REQUEST['id']).

'";') or die(mysql_error()); $time = microtime(); $query = sprintf("update clients set ps_time = '%s' where id = '%s'", mysql_real_escape_string($time), mysql_real_escape_string($_REQUEST['id'])); mysql_query($query) or die(mysql_error()); echo $time; } else{ $time = microtime(); $amount = $_REQUEST['amount']; $hash = $_REQUEST['hash']; $query = sprintf("INSERT INTO clients (amount,hash,cr_time) VALUES ('%s','%s','%s');", mysql_real_escape_string($_REQUEST['amount']), mysql_real_escape_string($_REQUEST['hash']), mysql_real_escape_string($time)); mysql_query($query) or die(mysql_error()); $id = mysql_insert_id(); echo $id." | ".

$time; } } ?>

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

Итак, перейду непосредственно к результатам испытаний.



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

То, что я увидел, меня сильно удивило.

А именно: nginx Запрос типа:

select count(*) from clients group by sec_time order by sec_time desc limit 0,20;

Показано, что среднее количество обработанных сессий: 205 штук , для среднего времени: 0,025 секунды.

(Здесь и далее сессия — это время между созданием записи по первому запросу и обновлением записи по второму запросу из потока).



| 205 | | 200 | | 202 | | 208 |



| 155930 | 0 | K | 0.36527600 1339369721 | 0.38711300 1339369721 | 2012-06-11 02:08:41 | | 155929 | 0 | K | 0.36156500 1339369721 | 0.38884600 1339369721 | 2012-06-11 02:08:41 |

Ubuntu показала, что все ядра загружены равномерно, примерно на 80%, трафик на Ubuntu шёл со скоростью 400 кб в секунду, а при выключении одного из ноутбуков ситуация вообще не менялась, и поэтому, я была гипотеза, что роутер медленный.

апач С теми же запросами я наблюдал следующую картину:

| 255 | | 247 | | 257 |



| 190582 | 0.102561082738713 | G | 0.46013900 1339370133 | 0.48647400 1339370133 | 2012-06-11 02:15:33 | | 190581 | 0.266181369901719 | W | 0.45496900 1339370133 | 0.47832300 1339370133 | 2012-06-11 02:15:33 |

Это означает, что количество запросов, обрабатываемых в секунду, было порядка 255 , что больше, чем на nginx, время обработки одного запроса не увеличилось и также осталось равным 0,025 секунды.

Все остальные характеристики остаются прежними

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

не хочется верить, что Apache быстрее Nginx. Возможно тормоза nginx связаны с необходимостью использования fastcgi, и есть лучший способ настроить его для работы с php, но я не сразу нашел как это сделать, так что, уважаемые хабры, возможно, вы сможете сделать какие-то выводы( например, что мой эксперимент вообще не имеет никакой ценности из-за субъективных параметров), или принять его результаты как есть.

В любом случае, спасибо, что уделили время :) P.S. Вспоминая классику: nginx, давай, до свидания.

Теги: #Nginx #Администрирование сервера #Apache #ubuntu #стресс-тест

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.