Apache and lighttpd replaced by nginx for PHP application
A while back I wrote an article Switching from Apache HTTP Server to Lighttpd – Installing Lighttpd. Back then I migrated static stuff to lighttpd but left the dynamic stuff (PHP) with Apache.
I was never really satisfied with the speed of our system under load. I tried and tried. I optimized a lot of stuff in the backend and with the database. Most of the time I found a switch to make the system just a bit faster. Read Retrospective on three years of Seagull development if you are interested in the whole story.
In the last couple of weeks I ran out of ideas on where to improve next (without the need of rewriting too much code). I remembered using Squid years ago. I had a look at the newest version (3.0) and my interest in Squid stopped pretty soon after reading through the documentation. It was just not the software I needed.
I dived into spreading the load to multiple backends using HAproxy which by the way has a super active community. Check the mailinglist. The maintainer Willy is doing a great job. Learning about HAproxy I stumbled across the webserver nginx (pronounced engine x) numerous times. Learning about nginx I stumbled across the reverse proxy Varnish which is the proxy solution I hoped Squid would be. Furtherdown the line I ran into PHP-FPM – the PHP FastCGI Process Manager – which should not stay unmentioned.
So I read lots of blog posts, mails from mailinglists, documentation, articles, visited several forums and also learned many new things in a few wikis. So after getting the idea I had my stack together: Varnish -> HAproxy -> nginx -> PHP -> MySQL
Time to test it out! Varnish comes in a relatively uptodate package for my favorite distribution OpenSuSE (currently running 10.3 on 6 systems). HAproxy is available in a fresh version. nginx is theoretically available. I cannot install it though because of a package management conflict. So I downloaded the source for the newest stable version (0.6.3 as time of writing) and compiled it.
wget http://sysoev.ru/nginx/nginx-0.6.32.tar.gz tar xzvf nginx-0.6.32.tar.gz cd nginx-0.6.32 ./configure --prefix=/opt/software/nginx-0.6.32 --user=nginx --group=nginx --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module make && make install
I did not need to install any extra packages. Frankly spoken I do have all the packages for compilation of C/C++ installed.
cd /opt/software ln -s /opt/software/nginx-0.6.32 nginx
I always set a symlink to the currently used package. That way it is easy to replace the package when new versions come out. I can compile and install the new version and just switch the symlink.
Unpack the PHP source:
tar xjvf php-5.2.6.tar.bz2
Patch the source:
gzip -cd php-5.2.6-fpm-0.5.8.diff.gz | patch -d php-5.2.6 -p1
Configure PHP (adjust your settings accordingly):
LDFLAGS="-L/usr/lib64" ./configure --with-curl --disable-debug --enable-libxml --enable-session --with-pcre-regex --enable-xml --with-bz2 --with-zlib --enable-exif --enable-inline-optimization --enable-soap --enable-sockets --with-xmlrpc --without-pear --with-libdir=lib64 --with-mysql --with-mysqli --enable-mbstring --with-mcrypt --with-mhash --with-mime-magic --with-jpeg-dir=/usr/lib64 --with-png-dir=/usr/lib64 --with-gd --enable-gd-native-ttf --with-ttf --with-freetype-dir --enable-ftp --enable-zend-multibyte --with-openssl --enable-force-cgi-redirect --with-pcre-regex --without-sqlite --without-mm --enable-fastcgi --enable-bcmath --enable-fpm --quiet --prefix=/opt/software/php5.2.6-fpm
Compile and install:
make & make install
Adjust the PHP-FPM settings to fit your needs. You can find more info on this and related subjects in the PHP-FPM documentation.
Have a look in the log files:
Now you can connect through your webserver to fast-cgi processes. I use nginx as webserver (see above). Advantages and disadvantes of fast-cgi vs. mod-based approaches et al have been covered elsewhere. For me this makes perfectly sense and works extremly well.
After playing around with Varnish for a while I decided I do not need HAProxy ATM. Varnish can do all the decisions I need to make based on HTTP headers. I configured Varnish’s config file (here: vcl.conf) by reading lots of examples on the net and trial and error.
If I find more time and anyone is interested I post more details on the configuration of nginx and Varnish. But for now I want to publish this post as it has been sitting here for a while already.
PS: If people say content is king they are absolutely right. But never forget in the internet speed is Kaiser!Google+