Last week I spent an afternoon switching my local WordPress installation from Apache, to Nginx. There are still a handful of unknowns, and quirks, that I need to get worked out to more accurately mimic our production setup, but, overall it wasn’t too bad and I learned a lot in the process.
At a high level, these two web servers take a different approach. Nginx focuses on serving up static content really really fast by using a different type of underlying architecture. Apache uses a blocking OS Thread Based approach, whereas Nginx uses a non-blocking Event Loop architecture. The differences are best explained by someone who wrote another type of ‘web server’ called node.js, that discusses the two different approaches at better length. You can find a YUI Theater video of his talk here – http://www.yuiblog.com/blog/2010/05/20/video-dahl/
When it came to configuring Nginx, the biggest hump for me was realizing that PHP is de-coupled from Nginx. With Apache you enable an add-on in the Apache Config file that just magically knows what to do when someone calls for a PHP file to be run (it’s probably less then magical and involves passing the request on to a fast-cgi wrapper to compile and run the request and return the result).
There is no such add-on for Nginx. So, although, it’s not terribly difficult to set up, once you realize that it is de-coupled, if you don’t realize that, it can be a little confusing. Ultimately, all you need to do is point Nginx at the appropriate port that php-fpm (fast-cgi process manager) is running on, and when it encounters PHP that needs to be executed, it passes it along.
This enables Nginx to focus what it is best at (static content), and allowing php-fpm to run separately. De-coupling this provides a few advantages. The first of which is that it makes Nginx even less of a non-blocking web server, allowing it to serve up tons of static or cached content while waiting on php-fpm to pass the result back.
De-coupling of any layer also usually results in greater optimizations for both layers, and better performance provided that the interfacing layer between the two doesn’t add more overhead than what is gained in the optimizations. Since Nginx and php-fpm most often run on the same server, and pass things back and forth on a pre-determined port, the interfacing layer has very little overhead.
In addition to the advantages added from de-coupling the system, here, we also gain some security advantages by using Nginx’s reverse proxy ability. That’s for another post though.