sean at chittenden.org
Mon Mar 14 15:15:16 PST 2005
> | There are better web servers than Apache for demanding loads;
> | ones that used a non-forking, event-driven I/O model.
> | Aolserver and thttpd come to mind.
> I tried thttpd a number of years ago, but due to its limited cgi
> support (at
> least at the time) I didn't do too much with it. It did seem fast,
thttpd is a favorite of mine because of the time I've spent in its guts
rewriting it for clients, but embedding PHP into it will never work
well because of the way the code is written and organization. Recently
I've been playing around with lighttpd and am very impressed. It's BSD
licensed (3 clause) and has quickly become my new webserver of choice
(*mutters something about Rails*). It even supports keep-alives well,
which is something that thttpd doesn't do too well. Here are some
benchmarks put out by a commercial webserver company, Lite Speed.
The lightspeed webserver guys are keen to point out that their
webserver is the fastest on the block, but I'm skeptical of their
results given the utility they're using for testing. I'm in the midst
of writing a kqueue(2)/pthreads(3) backed web-benchmark program that
will hopefully show that the gap between lighttpd and lite speed is
smaller than the above benchmarks point out (if there's any difference
at all). Any testing utility that's select(2) backed is going to suck
up more resources than the server.... but I digress. If you're doing
PHP, lighttpd should work very well for you and certainly be orders of
magnitude better than Apache.
Having skimmed through the lighttpd code, the areas that it could
*) pre-forking a pool of backends for CGI requests (lighttpd gets
crushed by litespeed here)
*) mmap(2)'ing buffers to reduce the overhead of writev(2)'ing data out
over the network (ie: reduce copying of userland data to the kernel)
*) use Boehm GC or make use of a memory pools that stay around longer
than a connection. Right now every connection gets its own memory pool
which is a problem in non-keep-alive connections. At the beginning and
end of a connection, a pool gets allocated and free'ed. Free'ed memory
from other connections is only reused by malloc(3), not by the OS.
*) A better method of appending data to buffers (ie, use the same idea
from Boehm's Cord library to reduce the costs of appending strings of
data). Right now it uses memcpy(3) and it should just add a pointer to
an array and realloc(3) the pointer array when the pointer array gets
full instead of copy'ing data around.
*) Divvy out requests to a pool of worker threads much the same way
that Cherokee does (a thttpd based webserver that's been adapted to use
pthreads... ie, thttpd on steroids)
The improvement should come with threaded processing and dispatching of
requests. Right now that's serialized and is the difference between
litespeed pro and litespeed. That's also one of the ways that Cherokee
makes its speed improvements over other webservers.
More information about the freebsd-performance