Kraft.im in Full HHVM Glory

If having a multi-network multi-site wasn’t enough of an edge case, I sidestepped over from PHP-FPM to HHVM. The former is used with NGINX to actually process the PHP code of a given site. HHVM is Facebook’s driven effort to the next generation of PHP in terms of performance. The goal is parity with PHP 5, but, in short, done better to make it faster.

You can read more about HHVM at their official site.

Vanessa has had a fever all day. The twins are getting sick. Olivia threw up tonight. Daddy need a bit of total geek time for his sanity…

https://twitter.com/Kraft/status/604122682863431681

Switching over was infinitely easier than I expected it to be. Very helpful, first off, is PHP-FPM and HHVM can run side-by-side. At the moment, this site is running HHVM, but my non-HTTPS sites on this install are still using PHP-FPM. (Let’s only break one site at a time, eh?). It is trivial to switch back, so absolutely worth it for the sake of trying it. Also, out of the box, WordPress on HHVM works like a charm.

Kudos to Facebook as the HHVM guide is about all you need to get started.

Since I already had a functional site on the server, I skipped ahead to installing HHVM per the instructions for my version of Ubuntu.

Once that was done, I replaced the existing FastCGI settings that were pointing to PHP-FPM with the included hhvm.conf settings. Restarted both HHVM and NGINX and presto.

The various sites I’ve checked performance aren’t giving me a clear sign that this is any better or worse immediately. I’m interested in seeing if there is any additional benefit on the long-term or if my site isn’t trafficked enough to realize the benefits of HHVM yet. Additionally, there are likely customized tweaks I could do to better leverage HHVM; time will tell.

In short, switching back and forth between PHP and HHVM is so amazingly simple, I needed this sentence to get me over 300 words.

Note: I specifically did not include command-by-command instructions on how to do all of this. Partly because HHVM’s docs were good enough, but moreso, this post will become stale. The commands to install HHVM in Ubuntu would be outdated as soon as the next version of Ubuntu is released since the release name is needed for adding the repo. Why would I give you exact commands to copy/paste if they will be wrong soon enough and there’s a canonical source for the information that’s just as easy to parse? I don’t know either.

Update! HHVM with PHP-FPM Fallback

Chris Wiegman very wisely pointed out that setting PHP-FPM as a fallback if HHVM goes down or errors out would be good. I agree, though didn’t set it up immediately. Then, HHVM crashed. I didn’t notice the server alert and my site was down for 12 hours. So, how to prevent this?

NGINX upstream to the rescue. I created a upstream.conf and added the following:

upstream php {
server unix:/var/run/hhvm/server.sock;
server unix:/var/run/php-fcgi.sock backup;
}

For me, I’m using Unix sockets since I’m all on one box and not currently looking to expand to multiple servers for this instance. Sockets save from loading the entire network stack, so should be a tiny bit of a performance boost. You could replace unix:/var/run/hhvm/server.sock with 127.0.0.1:9000 or whatever you’ve set HHVM and PHP-FPM to listen on.

Then, in the site’s nginx config, I replaced fastcgi_pass 127.0.0.1:9000; with fastcgi_pass php;.

In my case, at the same time, I modified my /etc/hhvm/server.ini file to replace hhvm.server.port = 9000 with hhvm.server.file_socket = /var/run/hhvm/server.sock to switch HHVM from listening on TCP 9000 to the unix socket.

Don’t forget to restart both nginx and hhvm.

After that, if hhvm fails, the nginx will automatically and gracefully fallback to PHP again.

~$ sudo /etc/init.d/hhvm stop
[ ok ] Stopping hhvm (via systemctl): hhvm.service.

~$ curl -I https://kraft.blog
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 03 Jun 2015 01:36:30 GMT
Content-Type: text/html; charset=UTF-8
(truncated)

~$ sudo /etc/init.d/hhvm start
[ ok ] Starting hhvm (via systemctl): hhvm.service.

~$ curl -I https://kraft.blog
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 03 Jun 2015 01:36:45 GMT
Content-Type: text/html; charset=UTF-8
X-Powered-By: HHVM/3.7.1
(truncated)