📜 ⬆️ ⬇️

Dirty stress test nginx vs apache

Good day!

Recently, I became interested in the question on which technologies it is possible to build an information system that would respond to more or less simple requests from customers, but as quickly and reliably as possible.
Having rummaged a little on the Internet, I certainly could not find a definite answer, so I decided to do my own little test.

Task

')
I formulated the task as follows:


Tests

It was originally planned to test a large number of options, namely:
self-written server on c ++
nginx + php
nginx + self-written module
apache + php
apache + self-written module
something samopisnoe on .NET

however, like any self-respecting sysadmin, I was lazy and I limited myself to nginx + php and apache + php , in the hope that I will do the rest of the experiments later (well, or after your comments on this article they will not be needed)
As a database, I used MySQL.

Base

In the table I made 3 control points:
1. Time to create a record (up to milliseconds)
2. The time the transaction ends (within milliseconds)
3. Record creation time (accurate to seconds)

3 checkpoint is needed in order to be able to understand how many records are created per second.
Total base turned out like this:

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(); 


Infrastructure

As a server, the only thing I had at hand was one of the last aspire one, with an Atom processor, 2 core, 4 flow, and installed on it 10 ubuntoi:

 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 


It is connected to the home router (canyon, model for 40 bucks approximately, 2 years old), 100 megabit connection, wire.

As bots for load creation I used the following machines:
2 laptops with core duo (one old Dell, the other old fujitsu), sub-accessory wires to the same router
1 beech laptop with i5 (new Dell) connected via wi-fi, also on the same router.

All settings were made on the basis of instructions in the first links of Google , so that there is no specific optimization of speech.

Bot

On all the laptops, windows 7 was installed, and according to this, the simplest option seemed to me to navigate the bot to c #, which in the loop created the required number of threads and started figuring the “transactions”.
The main bot code is as follows:

  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) ; } } 


Web part

A small PHP script that actually does everything I need, I implemented as follows:

 <?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; } } ?> 

The subtleties of the script and the bot are not so interesting, so I think you shouldn’t focus on them, and especially inquisitive minds will understand everything themselves, without much difficulty.

By this start immediately to the test results

results

Understanding that the test is absolutely not objective, starting from the fact that such things are not done on the desktop ubunt, ending with the need to use a normal switch, I still expected different results. What I saw surprised me greatly. Namely:

nginx

Request type:

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

Showed that the average number of processed sessions: 205 pieces , for an average time: 0.025 seconds.
(Session here, and further, I call the time between the creation of a record from the first request and the update of the record at the second request from the stream).
 | 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 |


Ubunt showed that all the cores were loaded evenly, about 80%, the traffic on Ubunta went at a speed of 400 kb per second, and when one of the beeches was disconnected, the situation did not change at all, therefore, I had a hypothesis that slows down the router.

apache

With the same requests, I observed the following picture:

| 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 |


This means that the number of processed requests per second was about 255 , which is more than by nginx, the processing time of one request did not increase, and it also remained equal to 0.025 seconds.
All other characteristics remain the same.

Bare conclusions


Honestly, it's hard to draw any conclusions from this, because I don’t want to believe that Apache is faster than nginx. Perhaps nginx’s brakes are related to the need to use fastcgi, and there is a better way to configure it to work with php, but I didn’t find out how to do it right away, so, dear hacks, you may draw some conclusions (for example, my the experiment is of no value at all because of the subjective parameters), or accept its results as is.

Anyway, thanks for the remote time :)

PS Remembering the classics: nginx, come on, bye.

Source: https://habr.com/ru/post/145689/


All Articles