APACHE -VS- NGINX. 2015 EDITION
The choice used to be clear:
- You want convenience – go with Apache
- If you want speed – then it’s Nginx
Or lighttpd. Or whatever, but NOT Apache web server. Sometimes they were even used in conjunction – Nginx on the front, to spoon-feed slower client connections and serve static content (using almost no memory for that), and Apache at the back, to generate dynamic content.
Digital ocean has covered the practical considerations of running one or the other (or both) very nicely, so I’m not going to. What I am going to tell you though is that it is outdated. Long gone the days when Nginx had a significant advantage over Apache.
If you run a dynamic website, such as WordPress, Apache can now be just as good in terms of speed, so instead of rushing over to Nginx, I’d like to suggest an alternative approach.
Disclaimer: this article is mostly focused on websites running on PHP, it is however also relevant to those running dynamic websites using any other apache module, such as mod_python, mod_ruby, mod_perl etc.
WHAT WAS WRONG WITH APACHE
You know what used to be the main problem with Apache? It’s that it was only possible to serve dynamic websites through Apache modules. For example, to serve a PHP-based website, Apache would use a module calledmod_php (module, that many websites use to this day) and that module used heaps of memory (pun intended).
Yet the actual problem was that one httpd process was only able to handle one connection at a time (think of httpd process as a separate program on your server that doesn’t like sharing resources with other programs).
So even if you were only serving static files such as css files, javascripts or images, Apache used separate processes to serve them, and all the extra memory. Whereas Nginx used so called events-based architecture that allowed single process to handle hundreds of connections.
What you may not know though, is that in version 2.4 (which has been around since 2012), Apache can now use the same method to handle connections, which Nginx used to be famous for.
Yes, now a single Apache process can handle tens, hundreds or even thousands of connections.
PROOF
To prove it, I want to share results from two sets of benchmarks I ran with each web server:- Serving static content
- Serving dynamic content
Both benchmarks were done on the same 4-core machine with 7.5G of RAM, configured to best of my knowledge.
SERVING STATIC CONTENT
Let’s start with static files. For this test, I used the same 150kb jpeg image file and I just kept fetching it at an increasing number of parallel requests using ab.
One thing I was interested in was how many such requests each one will handle per second. Here’s a result that says it all:
I take it you’re laughing out loud right now. Clearly Nginx smashed Apache into pieces. Well laugh no more and here’s why: unless your server is only serving static content, this benchmark is pretty much irrelevant.
If you are indeed serving static content only, then by all means go with Nginx, especially if you’re either already running more than one server, or considering running one more because your current static content server can hardly keep up.
Otherwise, here’s one thing from this particular benchmark that did interest me: how much memory will the server consume during the test? Here’s the result:
SERVER MEMORY USAGE WITH APACHE SERVER MEMORY USAGE WITH NGINXThe reason it is interesting, is that with a typical Apache configuration (e.g. mod_php), such a test would have killed Apache almost instantly.
Apache would have used the entire server memory and the server would have slowed down to a crawl. As a safeguard, one would likely have configured it to only serve a hundred or so requests in parallel, but then a lot of the requests would’ve been queued up and, consequentially, they would’ve take even more time to complete.
To summarize the results of this first test, when configured properly, Apache is now capable of handling an impressive amount of concurrent requests with very low memory footprint and in that regard, it is an acceptable choice even if your server is only serving static files.
SERVING DYNAMIC CONTENT
This is where things get really exciting.
If you are considering Apache or Nginx for your dynamic website, be it WordPress, Joomla, Drupal or any other 3rd party or in-house web app, what your server will be doing most of the time is running code.
In fact, the amount of time spent serving static files will be disproportionally low compared to dynamic content, therefore it’s way more important to see how well can Apache handle dynamic content and how that compares to Nginx.
Drumroll, please!
Exactly! They’re the same.
And the reason results are the same is that both Apache and Nginx are pretty much sleeping during this test. All they do is pass the request on to php-fpm (we’ll talk about it more later), wait for a response and then send it back to the user. And while they wait, they can keep serving static files without any need to launch extra processes for that.
In terms of memory, both servers have used the same amount of memory too.
So, when it comes to dynamic websites, Apache is now just as good an alternative as Nginx or any other events-based web server. And the reason is exactly that – Apache can now use events-based approach too, as long as you configure it to do so.
CONFIGURING APACHE PROPERLY
I mentioned in the beginning that Apache can be configured to use events instead of processes since version 2.4. Truth is, it has been available since 2.2, except that in version 2.2 it was considered experimental and in order to use this new approach, you would have to rebuild the server. Let’s not go down that path and switch to 2.4 instead (if you have not done so yet).
Before we configure Apache though, we must first set up php-fcgi. We’ll use php-fpm (which stands for PHP FastCGI Process Manager) that will act as a server that we’ll be forward requests to for PHP processing.
PHP-FPM
Depending on the OS and repository you are using, the actual command to get php-fpm installed will be different. I will assume CentOS/RHEL 6 but feel free to adapt it to your distribution of choice. On CentOS you would install it with:
1
|
# yum install php-fpm
|
There are several configuration files involved (could vary between different distributions):
1
2
|
/
etc
/
php
-
fpm
.
conf
-
main
configuration
file
/
etc
/
php
-
fpm
.
d
/
*
.
conf
-
additional
config
files
|
We’ll use a stock configuration file /etc/php-fpm.d/www.conf and we’ll make a few small changes:
1
2
3
4
|
;
listen
=
127.0.0.1
:
9000
listen
=
/
var
/
run
/
php
.
socket
listen
.
owner
=
apache
;
or
whatever
user
is
apache
running
under
listen
.
group
=
apache
;
likewise
|
Also it’s good to know what the main php-fpm controls are:
1
2
3
4
5
6
7
|
pm
=
dynamic
-
leave
it
there
so
more
child
processes
are
-
created
when
needed
pm
.
max_children
-
max
number
of
php
processors
to
run
pm
.
max_spare_servers
-
how
many
to
keep
when
the
workload
drops
down
pm
.
max_requests
-
how
many
user
requests
to
handle
before
-
recycling
.
Don'
t
leave
it
at
0
(
default
)
,
-
set
to
1000
if
not
sure
.
|
Once you’re done with the changes, start it and configure to start during server startup:
1
2
|
# chkconfig php-fpm on
# service php-fpm start
|
APACHE
First, check the version of Apache httpd server you are using (httpd -V should do it) and if you’re still on 2.2, let’s set up 2.4. One way to do it on CentOS 6 is through “CentOS Software Collections”:
1
2
|
# yum install centos-release-SCL
# yum install httpd24-httpd.x86_64
|
It will install Apache 2.4 with all of the files and configuration under /opt/rh/httpd24/root/etc/httpd/. I’ll leave all of the standard configuration options for you to handle (there’s usually not much to change there anyways), but here’s what you want to do to start using events-based architecture:
1
2
3
4
|
# cd /opt/rh/httpd24/root/etc/httpd/conf.modules.d
# nano 00-mpm.conf
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
LoadModule
mpm_event_module
modules
/
mod_mpm_event
.
so
|
Now create a new file, say, 05-php.conf to configure Apache to php-fpm interface:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# nano 05-php.conf
IfModule proxy_fcgi_module>
Proxy "unix:/var/run/php.socket|fcgi://php-fpm" timeout=300>
/Proxy>
/IfModule>
Directory "/path/to/web/root">
IfModule proxy_fcgi_module>
FilesMatch \.php$>
SetHandler
"proxy:fcgi://php-fpm/"
/FilesMatch>
/IfModule>
/Directory>
|
And start the server:
1
|
# service httpd24-httpd start
|
If you’re upgrading from 2.2, it’s probably a good idea to first start this new Apache on an alternative port, say 81 (that’s maybe as simple as changing Listen directive) and test it before you commit to the change. Once you’re good with it though, stop the old apache and reconfigure the startup options:
1
2
3
4
|
# service httpd stop
# chkconfig httpd off
# service httpd24-httpd start
# chkconfig httpd24-httpd on
|
SUMMARY
Apache httpd is a great web server and the new mpm_event module takes it to entirely new heights. Nginx can still outdo Apache in some edge cases (i.e. serving static content only), but when it comes to dynamic websites, which most of the web 2.0 is built on, Apache is now just as good of a choice as Nginx. And if you are already running mpm_event based configuration, I’d recommend to focus your optimization efforts elsewhere rather than looking at Nginx as an opportunity.
转载http://www.speedemy.com/apache-vs-nginx-2015/
I wrote a little while ago about how, for running PHP, Nginx was not faster than Apache. At first I figured that it would be and then it turned out not to be, though only by a bit.
But since Apache also has an event-based MPM I wanted to see if the opposite results were true; that if Apache were using its event MPM it would be about the same as Nginx. I had heard that Apache 2.2’s event MPM wasn’t great (it was experimental) but that 2.4 was better, possibly even faster, than Nginx.
So I had a few spare moments this Friday and figured I would try it out. I basically ran ab at concurrency levels of 1, 10, 25, 50, 100 and 1000. Like before the results surprised me.
The first run with Nginx was impressive. It peaked at 14,000 requests per second. Given my wimpy VM that I ran it on, those numbers are pretty good. What surprised me was that Apache was only half that. I will say for the record that I do not know how to tune the event MPM. But I don’t really have to tune Nginx to get 14k requests per second so I was expecting a little better from Apache. So I pulled out all of the LoadModule statements I could but still have a functional implementation of Apache. While the numbers were 25% better or so they were still well shy of what Nginx was capable of. Then I added the prefork MPM to provide a baseline. Again, I was surprised. The event MPM was faster than the prefork MPM for static content, but not by much.
So it seems that if you are serving static content Nginx is still your best bet. If you are serving static content from a CDN or have a load balancer in front of Apache which is running PHP then the prefork MPM is the way to go. While the event MPM will help with concurrency it will not help you speed up PHP and so is not really needed.
转载:http://www.eschrade.com/page/performance-of-apache-2-4-with-the-event-mpm-compared-to-nginx/
Apache 2.4 vs Nginx Benchmark Showdown
How the tests were performed:
I wanted to simulate a VPS environment similar to a basic Linode. A base install of Ubuntu Server 10.04 was installed in VMWare with an older/slower 7200RPM sata drive for storage. This drive was not in use by any other system during the test, nor were any other VMs active on the host. The guest was given 512MB of RAM and 1 CPU core of the host's 8 cores. The host's CPUs are dual Xeon X5365 @ 3Ghz.
Apache 2.2 was installed along with nginx 0.7.65, later Apache 2.4 was compiled on this same system.
Testing was performed using Apache JMeter on an 8 core Xeon workstation running Windows 7 and 32GB of RAM with a 1Gb/s link to the VMWare host. Requests per second were determined by rounding off the throughput displayed in the Summary Report listener. Each test was run until the requests per second stabilized.
The Apache 2.2 server was only tested with the Prefork MPM, while the Apache 2.4 server was tested with both Prefork and Event. Apache's KeepAlive setting was on throughout the testing and set at 2 seconds.
Update:
I received several requests to post memory usage statistics so I've updated the Jquery test with memory results. Again, care was not taken to keep the Apache builds consistent. It concerns me that the Prefork build of Apache 2.4 was using so much memory compared to the other Apache builds. Take these results with a grain of salt, but trust that Nginx definitely uses significantly less memory than Apache.
Update 2 - Nginx 1.0.12:
I received some flak for using an older version of Nginx, so I tested with Nginx 1.0.12 and it was around 4% slower than the results shown here.
Test 1 - 21KB text file
HTTP Server | Req/s |
---|---|
Apache 2.2 Prefork | 2220 |
Apache 2.4 Prefork | 2250 |
Apache 2.4 Event | 2300 |
Nginx | 2600 |
HTTP Server | Req/s |
---|---|
Apache 2.2 Prefork | 4400 |
Apache 2.4 Prefork | 4700 |
Apache 2.4 Event | 4810 |
Nginx | 6650 |
Test 3 - jquery.min.js (92KB)
HTTP Server | Req/s | Memory Usage |
---|---|---|
Apache 2.2 Prefork | 650 | 12MB |
Apache 2.4 Prefork | 770 | 72MB |
Apache 2.4 Event | 820 | 20MB |
Nginx | 1000 | 2MB |
Test 4 - PHP output of phpinfo()
HTTP Server | Req/s |
---|---|
Apache 2.2 Prefork | 525 |
Apache 2.4 Prefork | 575 |
Nginx FastCGI | 450 |
转载http://mondotech.blogspot.jp/2012/02/apache-24-vs-nginx-benchmark-showdown.html