1

For an article in a news paper, I'm benchmarking 5 different web servers (Apache2, Cherokee, Lighttpd, Monkey and Nginx).

The tests made consist of measuring the execution times as well as different parameters such as the number of request served per second, the amount of RAM, the CPU used, during a growing load of simultaneous clients (from 1 to 1.000 with a step of 10) each client sending 1.000.000 requets of a small fixed file, then of a medium fixed file, then a small dynamic content (hello.php) and finally a complex dynamic content (the computation of the reimbursment of a loan).

All the web servers are able to sustain such a load (up to 1.000 clients) but Apache2 which always stops to respond when the test reach 450 to 500 simultaneous clients.

My configuration is :

  • CPU: AMD FX 8150 8 cores @ 4.2 GHz
  • RAM: 32 Gb.
  • SSD: 2 x Crucial 240 Gb SATA6
  • OS: Ubuntu 12.04.3 64 bit
  • WS: Apache 2.2.22

My Apache2 configuration is as follows:

/etc/apache2/apache2.conf

LockFile ${APACHE_LOCK_DIR}/accept.lock
PidFile ${APACHE_PID_FILE}
Timeout 30
KeepAlive On
MaxKeepAliveRequests 1000000
KeepAliveTimeout 2
ServerName "fnux.net"
<IfModule mpm_prefork_module>
  StartServers         16
  MinSpareServers      16
  MaxSpareServers      16
  ServerLimit        2048 
  MaxClients         1024
  MaxRequestsPerChild   0
</IfModule>
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
AccessFileName .htaccess
<Files ~ "^\.ht">
  Order allow,deny
  Deny from all
  Satisfy all
</Files>
DefaultType None
HostnameLookups Off
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel emerg
Include mods-enabled/*.load
Include mods-enabled/*.conf
Include httpd.conf
Include ports.conf
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
Include conf.d/
Include sites-enabled/

/etc/apache2/ports.conf

NameVirtualHost *:8180
Listen 8180
<IfModule mod_ssl.c>
  Listen 443
</IfModule>
<IfModule mod_gnutls.c>
  Listen 443
</IfModule>

/etc/apache2/mods-available

<IfModule mod_fastcgi.c>
   AddHandler php5-fcgi .php
   Action php5-fcgi /cgi-bin/php5.external
   <Location "/cgi-bin/php5.external">
     Order Deny,Allow
     Deny from All
     Allow from env=REDIRECT_STATUS
   </Location>
 </IfModule>

/etc/apache2/sites-available/default

<VirtualHost *:8180>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/apache2
  <Directory />
    Options FollowSymLinks
    AllowOverride None
  </Directory>
  <Directory /var/www/>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    allow from all
  </Directory>
  ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
  <Directory "/usr/lib/cgi-bin">
    AllowOverride None
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    Order allow,deny
    Allow from all
  </Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel emerg
#####   CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /doc/ "/usr/share/doc/"
  <Directory "/usr/share/doc/">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 127.0.0.0/255.0.0.0 ::1/128
  </Directory>
  <IfModule mod_fastcgi.c>
    AddHandler php5-fcgi .php
    Action php5-fcgi /php5-fcgi
    Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
    FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
  </IfModule>
</VirtualHost>

/etc/security/limits.conf

* soft nofile 1000000
* hard nofile 1000000

So, I would trully appreciate your advice to setup Apache2 to make it able to sustain 1.000 simultaneous clients, if this is even possible.

TIA for your help. Cheers.


@Laszlo Valco: I do 100 per 100 aggree with your point and that's why I came here to ask for advice and help to configure Apache2 in order to make it able to sustain such a load.

Now, I'm confortable to do so for all the other web servers but I admit that I'm dumb and completely ignorant of the Apache2 settings.

BTW, the current Apache2 configuration above isn't the default one, but once again I agree it doesn't meet the need to sustain my tests.

So, could you be kind enough to explain how to set the numbers affecting the worker processes in a way that the 1.000 child process are available?

I guess it's in the section "IfModule mpm_prefork_module" of the file "/etc/apache2/apache2.conf" but I've no idea how to set the right values accordingly to both my hardware capabilities (especially the amount of RAM that is 32 Gb) and my need to reach 1.000 simultaneous connected clients.

Your expertise would be truly appreciated to help me to use the right values since even after long searches I wasn't able to find clear explanations about how to do so.

TIA for more info.

Cheers.

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
Fnux
  • 173
  • 1
  • 8
  • What mpm are you actually using? It should probably be [worker](http://httpd.apache.org/docs/2.2/mod/worker.html). – David Schwartz Oct 27 '13 at 02:20
  • As shown in the apache2.conf above, it's mpm_prefork_module. – Fnux Oct 28 '13 at 11:09
  • I changed my Apache2 configuration to use the mpm_worker_module but I still can't figure what's the best settings to use on my quite powerfull machine. Where could I find a clear and detailed documentation explaining how to configure Apache2? – Fnux Oct 28 '13 at 13:28
  • The Apache website documents every configuration option extensively. You can read the section about the MPM module you're using, there you'll find how the config options influence the way the server threads/processes are started and shut down. – Laszlo Valko Oct 29 '13 at 21:44

2 Answers2

1

When you use the threaded worker MPM, it only depends on how many resources you have available (CPU and memory); apache will happily run 1000 concurrent threads if you have, say 4GB available for it.

mod_prefork is deprecated and should be avoided for any serious application.

adaptr
  • 16,479
  • 21
  • 33
  • Thanks adaptr for your point. As described in my first post, I've 32 Gb of RAM. So, accordingly to documentation I've found, I must use the mpm_prefork_module in order to let Apache2 (2.2.22) respond to both static requests and dynamic requests (PHP). In this case, what should be the best settings to sustain 1.000 clients? Now, if this module is deprecated, what should I use? TIA for your advice. – Fnux Oct 27 '13 at 16:26
  • When you know what exactly you want, ask a directed question. This is not a polling site. – adaptr Oct 27 '13 at 16:27
  • I tought my question was clear enough: So, to be direct, what is the Apache2 configuration to use to sustain 1.000 simultaneaous clients sending both static and dynamic (PHP) requests on a machine that has an AMD FX 8150 8 core @ 4.2 GHz, 32 Gb of RAM and 2 SSD Crucial running Ubuntu 12.04.3 LTS 64 bit? Your advice and expertise would be trully appreciated. TIA. – Fnux Oct 27 '13 at 16:33
  • That's much too involved to detail to you on a forum site. I'd be rewriting the documentation. – adaptr Oct 27 '13 at 16:42
  • Dear adapt, if you don't want to answer more precisely, it's your right but in this case, please just don't post since such messages are clearly useless. BTW, I've absolutely no clue of what you're talking about! What documentation are you refering to? Anyhow, thanx. – Fnux Oct 28 '13 at 00:55
0

I'm not too convinced that your benchmark is much useful when done with configurations like that. Doing any performance benchmark with default (or similar to that) configurations seems to me a little pointless. If someone is interested in performance at all, it is imperative to adjust the configuration by cutting every performance-degrading feature not absolutely neccessary. Then why would this someone be interested in a benchmark not showing the real power of these servers, but instead showing what the default configuration thought to be useful?

So if the idea is to do a proper performance benchmark, then you should set up a real-life list of functional requirements, and do some research on how to configure these pieces of software to fulfill the functional requirements AND perform as well as possible. Apache default configuration is notoriously non-performance-friendly, for example.

And to help you out with your Apache configuration: set the numbers affecting the worker processes in such a way that the 1000 child process are always available.


Try these settings for MPM prefork:

StartServers       1024
MinSpareServers     128
MaxSpareServers    1024
ServerLimit        2048 
MaxClients         2048
MaxRequestsPerChild   0

or these for MPM worker:

ServerLimit          64
StartServers         32
MaxClients         2048
MinSpareThreads     128
MaxSpareThreads    1024
ThreadsPerChild      32

Also, please recognize that the <IfModule mpm_prefork_module> line will exclude that section unless you use that MPM module or change the module name in that line.

Laszlo Valko
  • 591
  • 6
  • 8
  • I'd be glad to set the numbers affecting the worker processes in a way that the 1000 clild process are always available if I knew how to do it. So, using the MPM_WORKER module, what parameters should I tune? TIA for you advice. – Fnux Oct 29 '13 at 16:26
  • Thank you so much. This realy helps. Both configurations are working fine. Now, I've to find out what's the best in performance for my mix of static and dynamic requests. Once again, thank you very much. I'll give you a link to my results once all the benchmarks will be done (i.e. within the end of the week). – Fnux Oct 31 '13 at 01:33