1 摘要Hiphop是由facebook 公司開發(fā)的應用程序,主要是將php代碼轉(zhuǎn)換成C++代碼進行高度優(yōu)化,然后由g++生成二進制文件。 官方說明hiphop要比apache+php節(jié)約50%的cpu; 經(jīng)測試,hiphop 要比nginx+fastcgi(加速器)的性能高出60%以上,要比nginx+fastcgi(無加速器)的性能高出150%左右。 本文對hiphop的部署、運行以及開發(fā)相關的規(guī)范和注意事項進行了詳細說明。 2 部署2.1 環(huán)境操作系統(tǒng)版本Centos需要在6.2以上才可以很好的支持。 2.2 安裝流程安裝環(huán)境支持建議通過yum方式進行安裝,通過手動安裝支持包的方式,會出現(xiàn)一些不可預見性的錯誤。 安裝流程如下: 我們設定我們的安裝目錄在/export/dev下 (1) yum 相關環(huán)境支持包 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最新源碼,并且配置環(huán)境變量,代碼我們會git指定某個版本進行部署。 環(huán)境變量: 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:///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./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:///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./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 這里注意,需要創(chuàng)建build文件夾,在build中cmake和make hiphop,如果在根目錄編譯則會與源碼混淆出現(xiàn)不可預見性的錯誤。 到此安裝hiphop的環(huán)境、第三方庫和hiphop源碼安裝完畢。 注: 上述的是官方提供的安裝方式,我們會將需要的安裝內(nèi)容進行打包和編寫腳本進行自動化安裝。 3 運行hiphop3.1 編譯(1) 編譯單個php文件 $HPHP_HOME/src/hphp/hphp test.php --keep-tempdir=1 --log=3 編譯成功會提示如下內(nèi)容: 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內(nèi)容并生成files.list文件: find . -name "*.php" > files.list 編譯files.list的php文件內(nèi)容 $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 編譯成功會提示如下內(nèi)容: 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
如果失敗會提示如下內(nèi)容: …… compiling and linking CPP files took 1'27" (87731 ms) wall time hphp failed running hphp took 1'36" (96498 ms) wall time
(3) 基本參數(shù)解釋 $HPHP_HOME/build/src/hphp/hphp:是hphp的編譯命令,可通過—help查看編譯參數(shù)的詳細內(nèi)容 --input-list:引入查找后的php生成的列表文件,如果要編譯單一的php文件則不用該參數(shù) -k[--keep-tempdir]:當k為真時(1),如果沒有指定輸出路徑,則會每次生成一個臨時文件夾在tmp目錄中,如(1)中沒有指定輸出目錄,則輸出到了臨時文件夾: creating temporary directory /tmp/hphp_knJ6dL ... --log:輸出的日志級別,默認-1;0是不輸出日志;1是只輸出錯誤日志;2是警告和錯誤日志;3是基本信息輸出;4完整的日志信息 --cluster-count:生成cpp 的數(shù)量,在生成二進制文件的路徑下的cpp文件夾中可以查看生成的cpp文件,數(shù)量1、2生成的數(shù)量為1和2,3以上的生成數(shù)量為n+1,0是每個php生成一個cpp文件。 --force:配置force=1,那么將在編譯時強制忽略php轉(zhuǎn)換二進制代碼中的警告和錯誤,只有在運行時才會發(fā)現(xiàn)這些錯誤。 -v "AllDynamic=true":-v 是配置參數(shù)以key-value的方式配置,詳細參數(shù)可見hiphop文檔,AllDynamic=true可支持動態(tài)的函數(shù)調(diào)用和動態(tài)方法調(diào)用,所以建議開啟。 -o:-o 文件輸出路徑,-o這個參數(shù)可以指定輸出的hiphop編譯好的二進制文件的路徑,如果不指定路徑,那么則會將編譯好的二進制內(nèi)容輸出到臨時文件夾。 3.2 執(zhí)行(1) 簡單執(zhí)行 進入生成二進制文件的目錄,然后執(zhí)行如下命令: ./program –m server 然后屏幕上會輸出如下內(nèi)容: 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 輸出如上內(nèi)容后,說明服務已經(jīng)啟動成功,我們可以通過瀏覽器訪問URL,如: http://192.168.12.63/test.php,成功后會顯示出頁面,如果失敗或者拋了錯誤,會在控制臺或日志中輸出具體錯誤的內(nèi)容。 -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 } } 配置內(nèi)容解釋: 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中,這樣就可以執(zhí)行每個進程到某個指定路徑下,-v是進行key-value這樣的配置選項的,key是我們配置中的選項,如配置中的最外層是Log,然后二級是File,依次類推,就可以通過Log.File.xxxx.xxx這樣的形式去配置,具體的配置需要參照配置文檔中的結(jié)構(gòu)。 (3) 開啟守護進程 Hiphop生成可執(zhí)行文件后,執(zhí)行可以采用多種模式進行運行,program的模式分為如下幾種: run | debug (d) | server (s) | daemon | replay | translate (t) 我們常用的一般是server(啟動命令行模式) 和daemon(守護進程) ./program –m server|daemon 啟動守護進程模式,最好配置日志,否則出現(xiàn)問題后,無法跟蹤 ./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監(jiān)聽端口和管理端口 設置http監(jiān)聽端口是 –p 端口 設置管理端口是 –admin-port 端口 例: ./program –m server –p 8080 –admin-port 18080 Hiphop生成的二進制代碼后,默認的http監(jiān)聽端口是80,管理端口8088 (5) Server配置 Server配置一些應用相關的基本信息,如壓縮、域名、IP、默認頁等等。 Server一般配置如下: Server { #域名 Host = www.xxx.com IP = 192.168.12.63 Port = 80 #線程數(shù)量 ThreadCount = 16 #post最大提交大小 MaxPostSize = 10MB #上傳文件的最大大小 UploadMaxFileSize = 10MB # 圖片處理文件內(nèi)存最大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的微調(diào)選項,libeventSyncSend允許將響應報文直接發(fā)給工作線程,從而使服務器響應更快 LibEventSyncSend = true #指定發(fā)送多少響應隊列 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 配置的環(huán)境變量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 |
|