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
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