Benchmark HHVM in FastCGI Mode

Benchmark HHVM in FastCGI Mode

Wiki

HipHop Virtual Machine (HHVM) is a process virtual machine based on just-in-time (JIT) compilation, serving as an execution engine for PHP and Hack programming languages. By using the principle of JIT compilation, executed PHP or Hack code is first transformed into intermediate HipHop bytecode (HHBC), which is then dynamically translated into the x86-64 machine code, optimized and naively executed. This contrasts to the PHP's usual interpreted execution, in which the Zend Engine transforms the PHP source code into opcodes as a form of intermediate code, and executes the opcodes directly on the Zend Engine's virtual CPU.

Official Website hhvm.com

According to their website, HHVM has realized over a 9x increase in web request throughput and over a 5x reduction in memory consumption for Facebook compared with the Zend PHP engine + APC (which is the current way of hosting a large majority of PHP applications).

This article will walk through the steps required to install HipHop VM 3.23.2 (rel) on Ubuntu 17.10 x64 (Intel® CoreTM i5-5350U CPU @ 1.80GHz, 1GB RAM). Note that HHVM doesn't support any 32-bit operating system and they have no plans to add support for 32 bit operating systems.

Installing HHVM

Installing HHVM is quite straightforward and shouldn't take more than a few minutes. Reference Prebuilt Packages for HHVM.

$ sudo apt-get install software-properties-common apt-transport-https
$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xB4112585D386EB94

$ sudo add-apt-repository https://dl.hhvm.com/ubuntu
$ sudo apt-get update
$ sudo apt-get install hhvm

Configure proxy for APT, add this line to your /etc/apt/apt.conf file:

Acquire::http::Proxy "http://yourproxyaddress:proxyport";
Acquire::https::Proxy "http://yourproxyaddress:proxyport";

To confirm that HHVM has been installed, type the following command:

$ hhvm --help

Using HHVM in the FastCGI Mode

Starting with version 3.0, HHVM can no longer be used in the server mode. This section will help you configure HHVM in the FastCGI mode with the Apache and Nginx servers.

HHVM-FastCGI works much the same way as PHP-FPM. HHVM, running in FastCGI mode, is started independently of the web server (Apache, Nginx, etc). It listens on either a TCP socket (conventionally localhost:9000) or a UNIX socket. The web server listens on port 80 or port 443 like it normally would. When a new request comes in, the web server either makes a connection to the application server or reuses one of the previously open connections, and communicates using FastCGI protocol. Therefore, the web server continues to decode HTTP protocol and supplies HHVM with information like the path of the file to be executed, request headers, and body. HHVM computes the response and sends it back to the web server using FastCGI again. Finally, the web server is in charge of sending the HTTP response to the client.

Running the Server

To run the server in FastCGI mode pass the following parameters to hhvm runtime:

$ hhvm --mode daemon -d hhvm.server.type=fastcgi -d hhvm.server.port=9000 -c /etc/hhvm/server.ini

The server will now accept connections on localhost:9000. To use a UNIX socket, use the Server.FileSocket option instead:

$ hhvm --mode server -d hhvm.server.type=fastcgi -d hhvm.server.file_socket=/var/run/hhvm/sock

To turn the server into a daemon, change the value of mode:

$ hhvm --mode daemon -d hhvm.server.type=fastcgi -d hhvm.server.file_socket=/var/run/hhvm/sock

Note, all the usual options that are accepted by hhvm runtime can be used in FastCGI mode as well. In particular, -d hhvm.admin_server.port=9001 will create an additional "admin" server listening on a port 9001.

Making it work with Apache 2.4

The recommended way of integrating with Apache is using mod_proxy mod_proxy_fcgi. Enable the modules, then in your Apache configuration, add a line as so:

ProxyPass / fcgi://127.0.0.1:9000/var/www/html/
# Or if you used a unix socket
# ProxyPass / unix://var/run/hhvm/sock|fcgi://127.0.0.1:9000/var/www/html/

This will route all the traffic to the FastCGI server. If you want to route only certain requests (e.g. only those from a subdirectory or ending *.php, you can use ProxyPassMatch, e.g.

ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1

Consult mod_proxy_fcgi docs for more details on how to use ProxyPass and ProxyPassMatch.

Also make sure to set up a DirectoryIndex in your Apache configuration like this:

<Directory /var/www/html/>
    DirectoryIndex index.php
</Directory>

This will try to access index.php when you send a request to a directory.

Get more information from FaceBook HHVM FastCGI.

Making it work with Nginx

Now nginx needs to be configured to know where your PHP files are and how to forward them to HHVM to execute. The relevant bit of nginx config lives at /etc/nginx/sites-available/default -- by default, it's looking in /usr/share/nginx/html for files to serve, but it doesn't know what to do with PHP.

HHVM included script sudo /usr/share/hhvm/install_fastcgi.sh will configure nginx correctly for stock installs. The important part is that it adds include hhvm.conf near the top of of the nginx config mentioned above -- this will direct nginx to take any file that ends in .hh or .php and send it to HHVM via fastcgi.

The default FastCGI configuration from Nginx should work just fine with HHVM-FastCGI. For instance you might want to add the following directives inside one of your location directives:

include snippets/fastcgi-php.conf; # nginx version: nginx/1.12.1 (Ubuntu)
fastcgi_pass   127.0.0.1:9000;
# or if you used a unix socket
# fastcgi_pass   unix:/var/run/hhvm/sock;

The result in your browser should look like this:

Benchmark HHVM in FastCGI Mode

Benchmark

I use bench.php script by Zend, we can find it at here.

Benchmark Results (Ubuntu 17.10 x64 (Intel® CoreTM i5-5350U CPU @ 1.80GHz, 1GB RAM)

PHP 7.2.0-2+ubuntu17.10.1+deb.sury.org+2 (cli) (built: Dec 7 2017 20:15:31) ( NTS )

$ php bench.php 
simple             0.056
simplecall         0.017
simpleucall        0.039
simpleudcall       0.038
mandel             0.157
mandel2            0.149
ackermann(7)       0.045
ary(50000)         0.004
ary2(50000)        0.003
ary3(2000)         0.073
fibo(30)           0.118
hash1(50000)       0.018
hash2(500)         0.026
heapsort(20000)    0.042
matrix(20)         0.039
nestedloop(12)     0.073
sieve(30)          0.031
strcat(200000)     0.005
------------------------
Total              0.934

HipHop VM 3.23.2 (rel)

$ hhvm bench.php 
simple             0.047
simplecall         0.059
simpleucall        0.043
simpleudcall       0.040
mandel             0.178
mandel2            0.188
ackermann(7)       0.025
ary(50000)         0.048
ary2(50000)        0.077
ary3(2000)         0.210
fibo(30)           0.046
hash1(50000)       0.045
hash2(500)         0.044
heapsort(20000)    0.159
matrix(20)         0.111
nestedloop(12)     0.069
sieve(30)          0.060
strcat(200000)     0.014
------------------------
Total              1.462
0.00 avg. rating (0% score) - 0 votes