Rich Atkinson

Rich Atkinson's Personal Blog

Long live Apache; Why NginX is the next king of httpd – and Lighttpd needs a little more work

Once upon a time…

It doesn’t seem long ago that I struggled to convince corporate IT that Apache on Linux was not only a viable alternative to IIS, but the superior choice. Whilst I’m not a big fan of windows for web servers – that’s largely a personal preference. IIS is actually a very capable web server; I’ve seen it stand up to quite a pounding. Of course, you need to patch it regularly, but the bottom line is it works perfectly fine. That is, until you try to configure it.

The biggest weakness in IIS is configurability.

Point and clicky configuration really is one of the stupidest ideas to come out of Redmond, particularly when that configuration can’t be edited or diffed as a simple text file. Have you ever tried replicating IIS settings to a DR machine? (Thank goodness for Vmware).

Configuration: Simple, but not stupid!

Apache really wins out in the configuration and configurability department. Apache is far more than just a web server, it’s the undisputed heavyweight champ of HTTP; if you can’t do it in Apache (either you’re doing something wrong, or) you can write a module to do it.

The King is here

In short, Apache is brilliant – it has set the benchmark as the practical, reliable utilitarian web server – it is probably responsible for more Linux server deployments than anything else.

In fact, I’d dare to say that Apache is the killer app for Linux.

I’ve deployed Apache in all shapes and sizes, in many configurations, as web servers, as reverse proxies, behind different load balancers and SSL accelerators – always with success. In short, this is why I don’t believe banking and finance will be in a hurry to move on from Apache and embrace the new darling of the RoR crowd, nginx.

The next great HTTPD

For all of the reasons above, I’ve never had cause to look beyond Apache. In fact, I didn’t know there was anything beyond Apache until recently, when I read that You Tube use Lighttpd to serve over 100 million crap videos, every day!

As anyone who is following this blog will know, I am currently using Django to develop a new web application (and I’m liking it a lot). Django is Python, and to use Python on Apache you are supposed to use mod_python. Now mod_python is an excellent piece of software, it’s very fast – and it exposes Apaches internal API. So, anything you can do by writing an Apache module in c, you can do in mod-python using python – and it’s pretty bloody fast.

The drawback is memory; mod-python has a bad rep for memory (although if you read Grahams comments on this post, you’ll see there are two sides to this story).

Regardless, Apache is a multithreaded beast – and so under moderate load you will start to require memory.

Memory Poor Computing

I’m building a web application to operate in a memory confined VPS, so, even with optimisations mod_python on Apache really isn’t ideal for me. Luckily, Django will also run as fastcgi, and while I haven’t done any serious load testing yet – early indications are that this seems reliable.

Continuing along the low memory meme – I have done a lot of testing with Apache over time, and what I have found is that Apache scales very well, so long as memory allows – and then it goes splat. In other words, to make Apache work under greater load, you have two options:

  1. Reduce Apaches memory footprint (you can actually get it quite small)
  2. Add more memory

Ostensibly, the number of concurrent requests Apache can handle is:

max requests = total physical mem – (RAM used by all other processes / size of an Apache process)

Anyway, with a 256MB VPS – you don’t even want to go there. No matter how much you optimise, you still end up with a built in scalability limit. So, I took a look at Lighttpd and Nginx.

Web Servers – The New Breed

These two web servers come from very different backgrounds, yet are actually rather similar. Both are so-called – asynchronous web servers, as opposed to the request-per-process model of Apache.

Lighttpd (pron: Lighty) is a single threaded web server which was famously developed to solve the C10K problem; that is, to serve 10,000 simultanious connections.

NginX (pron: Engine-X) originates from Russia; it was written for rambler.ru, which is Russias second bussiest web site. It runs with a single master process which delegates work to a small number of worker processes; so not quite single threaded – but light footed, shall we say.

My (limited) expereinces with NginX and Lighttpd.

First, I installed Lighttpd – to be fair, I didn’t really give it much of a chance – I read of several detailed accounts of memory leaks, enough to require scheduled restarts of the HTTPD. Now, I don’t really want to have to include scheduled restarts in my production servers (reminds me of running IIS2), nor do I want to have to reserve memory to cater for a leaking process, so I immediatley uninstalled lighttpd and instead took a look at NginX.

The Contender from the East

NginX is relatively new to the the English speaking world, the documentation was only recently translated from Russian to English; although the code is more mature than you might at first think.

I have to say that the NginX English wiki is excellent; the configuration is very similar to Apache – but with a slight bias towards c syntax (i.e. it’s easier to read with curly brackets and indentation). So, if you are familiar with configuring Apache, NginX is easy.

Familiarity breeds comfort

I use Ubuntu, where you can install NginX from Aptitude. Basically, this gives you a root conf file in /etc/nginx/nginx.conf – this contains the server wide settings, and it includes all files in the familiar sites-enabled (/etc/nginx/sites-enabled/) folder where you can add and remove http “server” definitions, or virtual servers in Apache parlance.

For the past few weeks, I’ve been using a single NginX instance with sites-enabled for: a static web server, a reverse proxy (for the django dev server) and a fastcgi server (for the django pre-production server) all at the same time, all without a problem.

Whilst I haven’t delved much deeper into the configuration potential, there is such a wealth of native modules available for NginX today, that I deeply suspect will make it as functional as Apache, for many use cases.

If I find myself experimenting with any of these (I intend to experiement with pre-compiled caches of gzipped content), I’ll be sure to talk about them here in detail.

Summary

In short – while NginX remains to be proven to the masses, it clearly is working well for some, myself included. I intend to do some serious load testing on NginX on RHEL when I get a chance, I’m curious to see how it behaves under stress, particularly with the SSL module.

If you’re starting to look beyond Apache, for whatever reason (I can’t think of any other than memory and massive scalability), definitely consider giving NginX a closer look.

This article, Long live Apache, Why NginX is the next king of httpd – and Lighttpd needs a little more work, is written by Richard Atkinson and first appeared on jetfar.com.

Written by Rich Atkinson

March 5, 2008 at 1:09 pm

Posted in Web Tech

8 Responses

Subscribe to comments with RSS.

  1. Hmmm, since you have read my comments, am surprised you haven’t also stumbled across mod_wsgi. For hosting WSGI applications capable applications (such as Django) embedded in Apache, mod_wsgi is faster than mod_python and has less memory overhead. The mod_wsgi module also incorporates a daemon mode such that one can get the same sorts of benefits of fastcgi but in a more self contained package that doesn’t require a separate adapter such as flup. Daemon mode of mod_wsgi even runs faster than mod_python even though separate processes are used.

    So, don’t give up on Apache just yet. :-)

    Graham Dumpleton

    March 5, 2008 at 4:13 pm

  2. Hi Graham,
    Thank you for stopping by and for leaving a comment.

    You know – I had noticed modwsgi in my browsing, but I am guilty of not really having given it fair consideration. Thank you for bringing it to my attention; I notice that it’s a topic close to your heart – I promise to look more closely in the coming weeks.

    I personally believe that removing any *moving part* from a configuration (eg: flup) is in principle, a very good thing. I will try mod_wsgi. I will certainly be doing some more organised load testing before launch, I would be missing out if I didn’t give modwsgi a good thrashing at the same time.

    I also noticed this: http://wiki.codemongers.com/NginxNgxWSGIModule

    They do say imitation is the strongest form of flattery!

    (PS: I certainly haven’t given up on Apache – but I am amazed at the capacity you can squeeze from a 256MB VPS if you really try)

    - rich

    rich

    March 5, 2008 at 4:52 pm

  3. The important thing to remember is that there is more than just performance. People get hung up on trying to find what they think is the fastest hosting solution. In practice though, the difference in performance between different hosting solutions for typical large applications using Django or other Python frameworks is less than a few percent when one looks at the total overhead of the application. In other words the bottleneck isn’t the hosting solution but the application and any database it talks to. Thus it is more important to find a solution which you are simply happy with, meeting your reliability requirements and that you at least find easy to configure and manage. That is all that is really important. Sure if you have got the next YouTube then performance is an issue, but very people would be in that situation.

    Anyway, have fun investigating the different solutions. Given you have a memory constrained VPS, as far as Apache goes I would recommend worker MPM, and run Django in 1 or 2 separate multithreaded processes using mod_wsgi daemon mode. This is best for keeping memory usage down. Because you would be using multithreading, just need to make sure your application is multithread safe. There have been a number of discussions in the past about memory constrained VPS systems on the Google group for mod_wsgi.

    Graham Dumpleton

    March 5, 2008 at 8:04 pm

  4. Rich,

    We have been living through *Severe* VPS performance problems for one of our projects for quite some time now.
    Based on what you’ve described above, I’m tempted to give NgineX a try.

    Thanks for the nice article and analyses.
    (BTW, clarity of diction is usually not considered to be the strongest of points amongst ‘techies’ – your writing really shines from this perspective too. :-) )

    Best wishes.

    Vic

    Vic

    March 27, 2008 at 11:10 am

  5. Hi Vic,
    Thank you kindly.

    I should point out that since then there are a couple of points to update.

    1) My experiences with nginx were excellent. The only slight complication is you need to manage your own fcgi processes, you can borrow some handy tools to do this from the lighttpd distro.

    2) Despite my good experiences, and probably because I’m a bit of a geek, I’ve given Graham’s modwsgi2 a shot – which meant changing to apache.

    3) I’m using worker mpm with 2-6 processes of 25 threads, and 1 mod_wsgi daemon per apache process.

    4) This uses only slightly more memory than nginx did, and theoretically should scale to my needs.

    5) I haven’t load tested this new config yet.

    6) I’ve ported this blog from super-slooow dreamhost to my slice – and it’s page load times are 1/10th of what they were. This is using php5 via fastcgi

    7) Apache fcgi is easier because the spawning is taken care of nicely

    8) Guess I should write another post!

    - rich

    rich

    March 27, 2008 at 9:06 pm

  6. I’ve had the same problem with my VPS(s) and I’m a django user too.
    Right now I’m using Nginx(or lighttpd in some machines) to serve static content and apache mpm worker to serve my applications.
    So far I’m pretty happy with it, the memory footprint was reduced and the stability is intact.

    Nuno Mariz

    May 23, 2008 at 10:29 am

  7. I’ve been using lighttpd for quite some time and suddenly it starts to time out during image transfer every so often in Firefox. Seems like someone has the same problem two years ago but it is remain unsolved!

    I’m trying out nginx soon.. next week if time permits.

    Hendry Lee

    September 28, 2008 at 3:47 am

  8. Currently in the process of migrating a site from Apache/mod_php to Nginx/fastcgi-php.

    Definitely recommend giving it a try, if you’re looking to squeeze more performance from a VP.

    Wing.

    Wing Wong

    March 14, 2009 at 2:15 am


Comments are closed.