Bismillaahir Rahmaanir Raheem
Alhamdulillaah, I’ve been able to make some major- and sorely-needed-upgrades to Audio Islam. Interestingly enough, for the vast majority of people, these changes won’t really be that visible as they are all behind-the scenes.
The desire to upgrade Audio Islam has been around for a long time, and I still have many more changes, particularly in relation to the code, that are pending. But I decided to focus on performance due to the vast surge in visitors that will come during the month of Ramadhaan, in shaaʾ Allaah. Therefore, I had to polish some things, upgrade others, and in some cases, fundamentally change them!
Prior to today, Audio Islam was running a typical LAMP setup – Red Hat Enterprise Linux 4, Apache HTTP Server, MySQL database server, & PHP Hypertext Preprocessor. Also typically, at the behest of the PHP developers, my Apache HTTP server was configured to operate in prefork mode, which, to put it simply, causes the web server to assign one process per web request.
For a site like Audio Islam, where currently the programming logic is rather limited and the bulk of the action involves downloading of large files, the cautions that call for using the prefork mode, as opposed to the more performant multi-threaded worker mode, are less urgent, so I opted for the more efficient mode due to Audio Islam‘s need for very high concurrency on rather modest server hardware. I’ve had to set the maximum number of clients in my webserver to over 700 and also offset the more popular mode of download to be FTP just to keep the website accessible, so I am very keen to seek out as much optimization as I can until I can move to another server that will sustain the site as well as this one in terms of bandwidth (currently, 20Mbit/s unmetered is keeping the site afloat, alhamdulillaah).
However, here is where the multi-threaded madness of PHP reared its ugly head. In truth, I am not entirely sure that I can lay the blame solely on PHP here, but as PHP is not generally multi-threaded enabled and intends to stay that way, I don’t feel so keen on removing them from the blame completely, either.
Before going further, here’s a summary of the specific versions of each package (before/after)
As I install all my servers from source on my aging Red Hat platform in order to get the latest versions easily, that means I have the pleasure of compiling all my packages from source (I haven’t figured-out how to make my own RPMs yet…). So, my first step was to compile Apache HTTP server, ensuring I enabled the worker MPM mode to enable multi-threading (a simple mistake I noticed when I saw the config summary included the old prefork MPM).
My configure command was as follows:
./configure --enable-modules=all --enable-mods-shared=all --with-mpm=worker
This went along very well. My next step was to compile MySQL, as I needed access to the client library in order to compile PHP with support for the database backend. Note that the coming of PHP 5.3 should obviate this as it will feature a native MySQL driver for PHP which shares the same license as PHP, which sparked the whole problem of the separation between PHP the MySQL client library.
Before I show the MySQL configure command, let me present the PHP one:
./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql --with-zlib --with-bz2 --enable-mbstring --with-mysqli --with-pdo-mysql --enable-zip
This is a pretty basic PHP configuration script, rather slim, but sufficient for what I needed. However, the configure script complained about a missing library for MySQL named “libmysqlclient_r”. I looked for it on my system, and while I found it, it was the wrong version. This is when I realizzed that I had to enable the thread-safe client in MySQL. So, I did this, using this configure command:
After a rather lengthy make & make install process, PHP was still complaining. I looked for libmysqlclient_r and found it, but PHP still kept complaining that it wasn’t under “/usr/local”. It didn’t matter that I explicitly instructed it to look at the install directory of my MySQL installation.
Anyway, after spending several hours trying to figure this out by researching online and trial-and-error, I decided enough was enough, and I was going to follow PHP’s recommendation of running it under FastCGI. However, I do not have a lot of experience getting Apache to run under FastCGI. Morever, as I didn’t need Apache’s power & flexibility for Audio Islam, I decided now was the time to go where I’ve wanted to go for a while – to host Audio Islam using lighttpd.
lighttpd (pronounced lighty) is a lightweight yet powerful HTTP server that is designed for low overhead and high performance. Despite these goals, it still hosts a slew of features that sufficed it to be the backend for Audio Islam, alhamdulillaah. Once I realized that I was going to go through with it, I stopped all my efforts at getting Apache HTTP working and focused on installing lighttpd. Amazingly enough, I discovered that the latest stable version, 1.4.19, was already available via yum for RHEL4! I quickly went ahead and install it and its fastcgi module. And, a short while later, after some configuration, I had Audio Islam up-and-running on lighttpd! Alhamdulillaah! It was rather surprising to see how it worked perfectly out of the box once I redirected it to my newly-fastcgi-compiled PHP. For reference, here’s the final configure command I used for compiling PHP to ultimately work on lighttpd:
./configure --enable-fastcgi --enable-discard-path --enable-force-cgi-redirect --with-mysql --with-zlib --with-bz2 --enable-mbstring --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql=/usr/local/mysql/bin/mysql_config --enable-zip
The first three arguments are from the lighttpd documentation, and the rest are what I wanted in the first place.
So, there you have it! Audio Islam is now running on top of lighttpd, alhamdulillaah. In shaaʾ Allaah this setup will enable the server to sail through Ramadhaan far smoother than previous years. I guess we’ll find out in a couple of weeks, in shaaʾ Allaah.