1 摘要
Hiphop是由facebook 公司开发的应用程序,主要是将php代码转换成C++代码进行高度优化,然后由g++生成二进制文件。
官方说明hiphop要比apache+php节约50%的cpu;
经测试,hiphop 要比nginx+fastcgi(加速器)的性能高出60%以上,要比nginx+fastcgi(无加速器)的性能高出150%左右。
本文对hiphop的部署、运行以及开发相关的规范和注意事项进行了详细说明。
2 部署
2.1 环境
操作系统版本Centos需要在6.2以上才可以很好的支持。
2.2 安装流程
安装环境支持建议通过yum方式进行安装,通过手动安装支持包的方式,会出现一些不可预见性的错误。
安装流程如下:
我们设定我们的安装目录在/export/dev下
(1) yum 相关环境支持包
sudo yum install git svn cpp make autoconf automake libtool patch memcached gcc-c++ cmake wget boost-devel mysql-devel pcre-devel gd-devel libxml2-devel expat-devel libicu-devel bzip2-devel oniguruma-devel openldap-devel readline-devel libc-client-devel libcap-devel binutils-devel pam-devel elfutils-libelf-devel
安装libmcrypt
cd /export
mkdir dev
cd dev
wget 'ftp://rpmfind.net/linux/epel/beta/6/x86_64/libmcrypt-devel-2.5.8-9.el6.x86_64.rpm'
wget 'ftp://rpmfind.net/linux/epel/beta/6/x86_64/libmcrypt-2.5.8-9.el6.x86_64.rpm'
sudo rpm -i libmcrypt-*.rpm
libmcrypt-devel-2.5.8-9.el6.x86_64.rpm和libmcrypt-2.5.8-9.el6.x86_64.rpm包下载后可进行直接安装。
(2) 获取hiphop 源码
cd /export/dev
git clone git://github.com/facebook/hiphop-php.git
cd hiphop-php
export CMAKE_PREFIX_PATH=`/bin/pwd`/../usr
export HPHP_HOME=`/bin/pwd`
export HPHP_LIB=`/bin/pwd`/bin
export USE_HHVM=1
cd ..
获取git hiphop最新源码,并且配置环境变量,代码我们会git指定某个版本进行部署。
环境变量:
CMAKE_PREFIX_PATH :是hiphop第三方支持库的安装地址,如/export/dev/usr
HPHP_HOME:是hiphop的目录地址,如/export/dev/hiphop-php
HPHP_LIB:是hiphop的库目录地址,如/export/dev/hiphop-php/bin
(3) 安装第三方库
l libevent
cd /export/dev
git clone git://github.com/libevent/libevent.git
cd libevent
git checkout release-1.4.14b-stable
cat ../hiphop-php/src/third_party/libevent-1.4.14.fb-changes.diff | patch -p1
./autogen.sh
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
git最新的libevent包,然后安装hiphop的libevent补丁,打好补丁后安装libevent。
l libCurl
cd /export/dev
git clone git://github.com/bagder/curl.git
cd curl
cat ../hiphop-php/src/third_party/libcurl-7.22.1.fb-changes.diff | patch -p1
./buildconf
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
git最新的libCurl库,然后安装hiphop的libcurl补丁,打好补丁后安装libCurl。
l libmemcached
wget http://launchpad.net/libmemcached/1.0/0.49/+download/libmemcached-0.49.tar.gz
tar -xzvf libmemcached-0.49.tar.gz
cd libmemcached-0.49
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
下载libmemcached库,然后进行安装。
l JEMalloc 3.0(可选)
wget http://www.canonware.com/download/jemalloc/jemalloc-3.0.0.tar.bz2
tar xjvf jemalloc-3.0.0.tar.bz2
cd jemalloc-3.0.0
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
下载JEMalloc库,然后进行安装
l Tbb
cd /export/dev
wget 'http://threadingbuildingblocks.org/uploads/77/187/4.0%20update%205/tbb40_20120613oss_src.tgz'
tar -zxf tbb40_20120613oss_src.tgz
cd tbb40_20120613oss
make
sudo mkdir -p /usr/include/serial
sudo cp -a include/serial/* /usr/include/serial/
sudo mkdir -p /usr/include/tbb
sudo cp -a include/tbb/* /usr/include/tbb/
sudo cp build/linux_intel64_gcc_cc4.4.6_libc2.12_kernel2.6.32_release/libtbb.so.2 /usr/lib64/
sudo ln -s /usr/lib64/libtbb.so.2 /usr/lib64/libtbb.so
cd ..
下载并安装tbb库
l Libdwarf
git clone git://libdwarf.git.sourceforge.net/gitroot/libdwarf/libdwarf
cd libdwarf/libdwarf
./configure
make
sudo cp libdwarf.a /usr/lib64/
sudo cp libdwarf.h /usr/include/
sudo cp dwarf.h /usr/include/
cd ../..
git最新libdwarf库并进行安装
l 安装libiconv
tar zxvf libiconv-1.13.1.tar.gz
cd libiconv-1.13.1
./configure
make
make install
cd ..
l 安装libunwind
wget 'http://download.savannah.gnu.org/releases/libunwind/libunwind-1.0.tar.gz'
tar -zxf libunwind-1.0.tar.gz
cd libunwind-1.0
autoreconf -i -f
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
(4) 安装hiphop
cd /export/dev/hiphop-php
git submodule init
git submodule update
export HPHP_HOME=`pwd`
export HPHP_LIB=`pwd`/bin
mkdir build
cd build
cmake ../
make
这里注意,需要创建build文件夹,在build中cmake和make hiphop,如果在根目录编译则会与源码混淆出现不可预见性的错误。
到此安装hiphop的环境、第三方库和hiphop源码安装完毕。
注:
上述的是官方提供的安装方式,我们会将需要的安装内容进行打包和编写脚本进行自动化安装。
3 运行hiphop
3.1 编译
(1) 编译单个php文件
$HPHP_HOME/src/hphp/hphp test.php --keep-tempdir=1 --log=3
编译成功会提示如下内容:
running hphp...
creating temporary directory /tmp/hphp_knJ6dL ...
parsing inputs...
parsing inputs took 0'00" (34 ms) wall time
pre-optimizing...
pre-optimizing took 0'08" (8175 ms) wall time
analyze includes...
analyze includes took 0'00" (0 ms) wall time
inferring types...
inferring types took 0'00" (56 ms) wall time
post-optimizing...
post-optimizing took 0'00" (68 ms) wall time
creating CPP files...
creating CPP files took 0'00" (256 ms) wall time
saving code errors...
compiling and linking CPP files...
compiling and linking CPP files took 1'09" (69308 ms) wall time
all files saved in /tmp/hphp_knJ6dL ...
running hphp took 1'18" (78058 ms) wall time
(2) 编译整个目录的php文件
首先,在php应用目录,查找php内容并生成files.list文件:
find . -name "*.php" > files.list
编译files.list的php文件内容
$HPHP_HOME/build/src/hphp/hphp --input-list=files.list -k 1 --log=3 \
--cluster-count=50 \
-v "AllDynamic=true" –o /export/hphp_project/test
编译成功会提示如下内容:
running hphp...
parsing inputs...
parsing inputs took 0'00" (43 ms) wall time
pre-optimizing...
pre-optimizing took 0'08" (8208 ms) wall time
analyze includes...
analyze includes took 0'00" (0 ms) wall time
inferring types...
inferring types took 0'00" (43 ms) wall time
post-optimizing...
post-optimizing took 0'00" (69 ms) wall time
creating CPP files...
creating CPP files took 0'00" (291 ms) wall time
saving code errors...
compiling and linking CPP files...
compiling and linking CPP files took 1'09" (69585 ms) wall time
all files saved in /export/hphp_project/test_a/ ...
running hphp took 1'18" (78437 ms) wall time
如果失败会提示如下内容:
……
compiling and linking CPP files took 1'27" (87731 ms) wall time
hphp failed
running hphp took 1'36" (96498 ms) wall time
(3) 基本参数解释
$HPHP_HOME/build/src/hphp/hphp:是hphp的编译命令,可通过—help查看编译参数的详细内容
--input-list:引入查找后的php生成的列表文件,如果要编译单一的php文件则不用该参数
-k[--keep-tempdir]:当k为真时(1),如果没有指定输出路径,则会每次生成一个临时文件夹在tmp目录中,如(1)中没有指定输出目录,则输出到了临时文件夹:
creating temporary directory /tmp/hphp_knJ6dL ...
--log:输出的日志级别,默认-1;0是不输出日志;1是只输出错误日志;2是警告和错误日志;3是基本信息输出;4完整的日志信息
--cluster-count:生成cpp 的数量,在生成二进制文件的路径下的cpp文件夹中可以查看生成的cpp文件,数量1、2生成的数量为1和2,3以上的生成数量为n+1,0是每个php生成一个cpp文件。
--force:配置force=1,那么将在编译时强制忽略php转换二进制代码中的警告和错误,只有在运行时才会发现这些错误。
-v "AllDynamic=true":-v 是配置参数以key-value的方式配置,详细参数可见hiphop文档,AllDynamic=true可支持动态的函数调用和动态方法调用,所以建议开启。
-o:-o 文件输出路径,-o这个参数可以指定输出的hiphop编译好的二进制文件的路径,如果不指定路径,那么则会将编译好的二进制内容输出到临时文件夹。
3.2 执行
(1) 简单执行
进入生成二进制文件的目录,然后执行如下命令:
./program –m server
然后屏幕上会输出如下内容:
mapping self...
mapping self took 0'00" (35 ms) wall time
loading static content...
searching all files under source root...
analyzing 342 files under source root...
loaded 0 bytes of static content in total
loading static content took 0'00" (5 ms) wall time
page server started
admin server started
all servers started
输出如上内容后,说明服务已经启动成功,我们可以通过浏览器访问URL,如:
http://192.168.12.63/test.php,成功后会显示出页面,如果失败或者抛了错误,会在控制台或日志中输出具体错误的内容。
-m server采用的是非守护进程模式启动,默认端口是80,默认管理端口是8088
(2) 配置日志
配置日志格式是和apache的日志格式一致的,详细配置日志格式可参照apache的配置,下面进行配置一个日志的demo:
Log {
Level = Info
UseLogFile = true
File = /export/hphp_project/info.log
# access log settings
AccessLogDefaultFormat = %h %l %u %t \"%r\" %>s %b
Access {
* {
File = /export/hphp_project/access.log
Format = %h %l %u %t \"%r\" %>s %b
}
}
# admin server logging
AdminLog {
File = /export/hphp_project/ admin.log
Format = %h %t %s %U
}
}
配置内容解释:
Level: None (default) | Error | Warning | Info | Verbose(完整)
File:是输出日志的路径,最外层的File,上面配置为info.log的日志是记录服务日志信息的。
Access中的File是记录访问的日志信息的,可进行自定义每种访问类型的日志格式如(*.php,*.jpg),也可采用默认的日志格式进行输出,日志格式和apache 的日志配置一致。
AdminLog:是配置管理平台日志的
注:
File的路径需要采用绝对路径,相对路径在server模式下没有问题,可以正常输出日志,但是在守护进程(daemon)模式下必须用绝对路径日志才可以输出日志。
这个配置在一个文件中,然后在启动程序时进行加载即可,配置文件名字为program.conf,如:
./program –m server –c program.conf
这样配置文件即加载,如果启动时没有提示配置错误那么即加载成功,如果提示了加载错误,那么需要查找配置中的问题进行修改后重新启动。
如果在启动多进程时,那么输出的日志最好进行每个进程一个,那么配置日志就可以如此配置:
./program –m server –c program.conf -v “Log.File=/export/hphp_project/info_8080.log”
这样就覆盖了program.conf中的File地址,输出日志到info_8080.log中,这样就可以执行每个进程到某个指定路径下,-v是进行key-value这样的配置选项的,key是我们配置中的选项,如配置中的最外层是Log,然后二级是File,依次类推,就可以通过Log.File.xxxx.xxx这样的形式去配置,具体的配置需要参照配置文档中的结构。
(3) 开启守护进程
Hiphop生成可执行文件后,执行可以采用多种模式进行运行,program的模式分为如下几种:
run | debug (d) | server (s) | daemon | replay | translate (t)
我们常用的一般是server(启动命令行模式) 和daemon(守护进程)
./program –m server|daemon
启动守护进程模式,最好配置日志,否则出现问题后,无法跟踪
./program –m daemon –c program.conf –v “Log.File=/export/logs/program.log”
我们应用的日志配置采用(2)中的,输出日志到/export/logs/program.log,如果不配置日志,在守护进程模式下会提示:
Log file not specified under daemon mode.\n\n错误,守护进程模式下配置日志需要绝对路径
(4) 开启多进程
开启多进程可对program 的负载进行均匀分摊提高吞吐能力;
开启多进程需要设置program的http监听端口和管理端口
设置http监听端口是 –p 端口
设置管理端口是 –admin-port 端口
例:
./program –m server –p 8080 –admin-port 18080
Hiphop生成的二进制代码后,默认的http监听端口是80,管理端口8088
(5) Server配置
Server配置一些应用相关的基本信息,如压缩、域名、IP、默认页等等。
Server一般配置如下:
Server {
#域名
Host = www.xxx.com
IP = 192.168.12.63
Port = 80
#线程数量
ThreadCount = 16
#post最大提交大小
MaxPostSize = 10MB
#上传文件的最大大小
UploadMaxFileSize = 10MB
# 图片处理文件内存最大byte
ImageMemoryMaxBytes = UploadMaxFileSize * 2
#默认页
DefaultDocument = index.php
#404页
ErrorDocument404 = 404.php
#500页
ErrorDocument500 = 500.php
#压缩级别1-9;0是不压缩
GzipCompressionLevel = 3
#启用keepAlive
EnableKeepAlive = true
#允许分块编码response
EnableEarlyFluh = true
#强制分块编码reponse 不管客户端是否接受
ForceChunkedEncoding = false
#允许文件上传
EnableFileUploads = true
#这是libevent的微调选项,libeventSyncSend允许将响应报文直接发给工作线程,从而使服务器响应更快
LibEventSyncSend = true
#指定发送多少响应队列
ResponseQueueCount = 0
#连接超时时间
ConnectionTimeoutSeconds=1
#默认编码
DefaultCharsetName = UTF-8
}
这个是添加到配置文件中的,然后通过-c 添加即可如:
./program –m server –c program.conf
也可以针对某个选项进行单一配置,用key-value形式,如
./program –m server -v Server. DefaultCharsetName=UTF-8
4 扩展引入
在CMake/HPHPFind.cmake文件的最后位置添加上这些引用
include_directories(/export/dev_hhvm/usr/include)
/export/dev_hhvm/usr/lib/mongodb_c_driver/libmongoc.so)
target_link_libraries(${target} /export/dev_hhvm/usr/lib/mongodb_c_liulei/libmongoc.so)
#ICE
# include_directories(/export/huzhiguang/files/Ice-3.4.1/include)
include_directories(/export/dev_hhvm/usr/include/freetds)
include_directories(/export/dev_hhvm/usr/include/Ice)
target_link_libraries(${target} /export/huzhiguang/files/Ice-3.4.1/lib64/libIce.so)
target_link_libraries(${target} /export/huzhiguang/files/Ice-3.4.1/lib64/libIceUtil.so)
# target_link_libraries(${target} /export/dev_hhvm/usr/lib/Ice/libIce.so)
# target_link_libraries(${target} /export/dev_hhvm/usr/lib/Ice/libIceUtil.so)
# target_link_libraries(${target} /export/servers/freetds/lib/libsybdb.so)
target_link_libraries(${target} /export/dev_hhvm/usr/lib/freetds/libsybdb.so)
target_link_libraries(${target} /export/dev_hhvm/usr/lib/fastlz/fastl
5 Hiphop 配置的环境变量
BOOST_INCLUDE=/export/servers/boost-1.50/include/
BOOST_LIB=/export/servers/boost-1.50/lib
export BOOST_INCLUDE BOOST_LIB
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/export/servers/gmp-4.3.2/lib:/export/servers/mpc-1.0/lib:/export/servers/mpfr-3.1.1/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/export/servers/gcc-4.6.1/lib64
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$BOOST_INCLUDE:$BOOST_LIB
export PATH=/export/servers/gcc-4.6.1/bin:$BOOST_INCLUDE:$BOOST_LIB:$PATH
export CMAKE_PREFIX_PATH=/export/dev_hhvm/usr/
export HPHP_HOME=/export/dev_hhvm/hiphop-php_hzg
export HPHP_LIB=$HPHP_HOME/bin
export USE_HHVM=1
export LANG="C"
ulimit -c unlimited
export ICE_HOME=/export/huzhiguang/files/Ice-3.4.1
export PATH=/export/huzhiguang/files/Ice-3.4.1:$PATH
export DB_HOME=/export/huzhiguang/files/db-4.8.30.NC
export PHP_HOME=/export/servers/php-5.3.5
export PHP_BIN=$PHP_HOME/bin
export PATH=$PHP_BIN:$PATH
export PATH=$PATH:/export/servers/freetds/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/export/servers/freetds/lib
export PATH=/export/servers/freetds/include:/export/servers/freetds/lib:$PATH