• Nginx + PHP-FPM + APC=绝妙的组合
    时间:2010-08-02   作者:佚名   出处:互联网

    本文将介绍目前让PHP最快的方法:Nginx + PHP-FPM + APC,看似有些复杂,实际上我们只需要几个步骤就可以完成,并且性能远超Apache,有兴趣的朋友不妨去试一试。

    本文所介绍的方法应该是目前让PHP最快的办法:Nginx + PHP-FPM + APC。我们将从安装Nginx http服务器、PHP和PHP-FPM补丁,以及APC,详细的讲解这种方法的具体配置及应用,最终的效果如何?相信会让你大吃一惊。

    背景

    过去两年多来,我们的网站一直运行Apache+mod_php模块,大多数时候这个组合应付得过来,但随着流量的增加,我们注意到Apache已 经显得很吃力了,它开始疯狂地吃内存,CPU也被全部抢占去了,我们需要找到一个更快的方法来解决问题。

    Nginx是一个不错的选择,很多指标都超过了Apache,如I/O、CPU、内存和请求数/秒等,如果需要,随时可以从Google搜索相关信 息。从我个人的测试结果来看,Nginx和Apache之间的差异是很明显的,不好意思,因为是非正式测试,因此相关数字我就不公布了,这也不是本文的重 点。让我更自信的是,我只需要几个步骤就可以让性能远超Apache。

    PHP-FPM?

    很多人配置Nginx时可能都会选择来自LightTPD项目的spawn-fcgi解析PHP,但使用spawn-fcgi有些问题,因此我打算 放弃它另觅别的办法。PHP-FPM是PHP FastCGI Process Manager的缩写,即PHP FastCGI进程管理器,实际上它是PHP的一个补丁,旨在将FastCGI进程管理整合进PHP包中。

    注意:即使你坚持使用Apache,也有很多原因跳过mod_php,直接通过FastCGI解析PHP。使用mod_php时,Apache处理 载入PHP的每个请求会载入所有的库,这是一个巨大的无畏开销。如果使用FastCGI,PHP的行为更象应用程序服务器,PHP-FPM以及 spawn-fcgi按需要载入和杀掉PHP实例,这样做有很多好处,其中很重要的一点就是减少内存开销。

    让我们开始吧

    我们使用的是全新安装的Ubuntu 8.10 Intrepid,第一件事情是安装所有的依赖包。

    1. sudo apt-get install make bison flex gcc patch autoconf subversion locate  
    2. sudo apt-get install libxml2-dev libbz2-dev libpcre3-dev libssl-dev zlib1g-dev libmcrypt-dev libmhash-dev libmhash2 libcurl4-openssl-dev libpq-dev libpq5 libsyck0-dev
    3.  

    准备好依赖包之后,我们就可以开始。

    编译PHP

    我们下载的是PHP 5.2.8源代码包,还有对应的PHP-FPM补丁,我们先打上补丁,然后再编译。

    1. cd /usr/local/src/  
    2. sudo wget http://us.php.net/get/php-5.2.8.tar.gz/from/this/mirror  
    3. sudo tar zvxf php-5.2.8.tar.gz  
    4. sudo wget http://php-fpm.anight.org/downloads/head/php-5.2.8-fpm-0.5.10.diff.gz  
    5. sudo gzip -cd php-5.2.8-fpm-0.5.10.diff.gz | sudo patch -d php-5.2.8 -p1  
    6. cd php-5.2.8  
    7. sudo ./configure --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib --enable-mbstring --disable-pdo --with-pgsql --with-curl --disable-debug --enable-pic --disable-rpath --enable-inline-optimization --with-bz2 --with-xml --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --with-mhash --enable-xslt --enable-memcache --enable-zip --with-pcre-regex  
    8. sudo  make all install  
    9. sudo  strip /usr/local/bin/php-cgi 

    如果在运行上面命令时遇到错误,很可能是因为缺少依赖包造成的。另外,确保你正确启用和禁用了特定的PHP配置选项。紧接着我们通过PECL安装一 些将会用到的模块:

    1. sudo pecl install memcache  
    2. sudo pecl install apc  
    3. sudo pecl install syck-beta 

    在安装apc模块时,请务必关闭Apache选项,如果你没有关闭,它也会提醒你。接下来复制我们常用的php.ini:

    1. sudo cp /usr/local/src/php-5.2.8/php.ini-recommended /usr/local/lib/php.ini 
    2.  

    最后,我们建立符号链接:

    1. sudo mkdir /etc/php/  
    2. sudo ln -s /usr/local/lib/php.ini /etc/php/php.ini  
    3. sudo ln -s /usr/local/etc/php-fpm.conf /etc/php/php-fpm.conf 

    PHP编译到此结束,剩下要做的事情是修改php-fpm.conf设置,用文本编辑器打开/etc/php/php-fpm.conf,将进程属 主用户修改为www-data,这个文件比较大,因此最好使用搜索功能,我想修改的值分别位于51、52、63和66行。

    1. <value name="owner">www-datavalue> 
    2. <value name="group">www-datavalue> 
    3. <value name="user">www-datavalue> 
    4. <value name="group">www-datavalue> 

    Nginx

    和编译PHP一样非常简单:

    1. cd ..  
    2. sudo wget http://sysoev.ru/nginx/nginx-0.6.35.tar.gz  
    3. sudo tar zxvf nginx-0.6.35.tar.gz  
    4. sudo rm -f nginx-0.6.35.tar.gz  
    5. cd nginx-0.6.35  
    6. sudo ./configure --sbin-path=/usr/local/sbin --with-http_ssl_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module  
    7. sudo make && sudo make install 

    再创建一个链接:

    1. sudo ln -s /usr/local/nginx/conf /etc/nginx 
    2.  

    下一步是可有可无的,但我一直使用至今,说说也无妨。打开/etc/nginx/nginx.conf,最终修改结果如下:

    1. user  www-data;  
    2. worker_processes  6;  
    3.  
    4. events {  
    5.     worker_connections  1024;  
    6. }  
    7.  
    8. http {  
    9.     include       mime.types;  
    10.     default_type  application/octet-stream;  
    11.     sendfile        on;  
    12.     keepalive_timeout  10 10;  
    13.  
    14.     gzip  on;  
    15.     gzip_comp_level 1;  
    16.     gzip_proxied any;  
    17.     gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;  
    18.  
    19.         log_format main '$remote_addr - $remote_user [$time_local] '  
    20.                   '"$request" $status  $body_bytes_sent "$http_referer" '  
    21.                   '"$http_user_agent" "$http_x_forwarded_for"';  
    22.  
    23.         access_log  /var/log/nginx_access.log  main;  
    24.  
    25.         error_log  /var/log/nginx_error.log debug;  
    26.  
    27.         include /usr/local/nginx/sites-enabled/*;  

    我们也设置了一些FastCGI参数,让PHP不会噎着,也可以避免Nginx 503错误,打开/etc/nginx/fastcgi_params,添加以下参数:

    1. fastcgi_connect_timeout 60;  
    2. fastcgi_send_timeout 180;  
    3. fastcgi_read_timeout 180;  
    4. fastcgi_buffer_size 128k;  
    5. fastcgi_buffers 4 256k;  
    6. fastcgi_busy_buffers_size 256k;  
    7. fastcgi_temp_file_write_size 256k;  
    8. fastcgi_intercept_errors on; 

    最后,我们创建一个SystemV风格的启动脚本,保存为/etc/init.d/nginx。

    1. #! /bin/sh  
    2. ### BEGIN INIT INFO  
    3. # Provides:          nginx  
    4. # Required-Start:    $all  
    5. # Required-Stop:     $all  
    6. # Default-Start:     2 3 4 5  
    7. # Default-Stop:      0 1 6  
    8. # Short-Description: starts the nginx web server  
    9. # Description:       starts nginx using start-stop-daemon  
    10. ### END INIT INFO  
    11.  
    12. PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin  
    13. DAEMON=/usr/local/sbin/nginx  
    14. NAME=nginx 
    15. DESC=nginx 
    16.  
    17. test -x $DAEMON || exit 0  
    18.  
    19. # Include nginx defaults if available  
    20. if [ -f /etc/default/nginx ] ; then  
    21.         . /etc/default/nginx  
    22. fi  
    23.  
    24. set -e  
    25.  
    26. case "$1" in  
    27.   start)  
    28.         echo -n "Starting $DESC: "  
    29.         start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \  
    30.                 --exec $DAEMON -- $DAEMON_OPTS  
    31.         echo "$NAME."  
    32.         ;;  
    33.   stop)  
    34.         echo -n "Stopping $DESC: "  
    35.         start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \  
    36.                 --exec $DAEMON  
    37.         echo "$NAME."  
    38.         ;;  
    39.   restart|force-reload)  
    40.         echo -n "Restarting $DESC: "  
    41.         start-stop-daemon --stop --quiet --pidfile \  
    42.                 /usr/local/nginx/logs/$NAME.pid --exec $DAEMON  
    43.         sleep 1  
    44.         start-stop-daemon --start --quiet --pidfile \  
    45.                 /usr/local/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS  
    46.         echo "$NAME."  
    47.         ;;  
    48.   reload)  
    49.       echo -n "Reloading $DESC configuration: "  
    50.       start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \  
    51.           --exec $DAEMON  
    52.       echo "$NAME."  
    53.       ;;  
    54.   *)  
    55.         N=/etc/init.d/$NAME  
    56.         echo "Usage: $N {start|stop|restart|force-reload}" >&2  
    57.         exit 1  
    58.         ;;  
    59. esac  
    60.  
    61. exit 0 

    不要忘了设置可执行权限。

    设置你的网站

    这一阶段的工作主要按你自己的习惯完成,这里仅做一个粗略的介绍。首先我们创建一个目录来存放我们的网站配置文件:

    1. sudo mkdir /usr/local/nginx/sites-enabled  
    2. sudo ln -s /usr/local/nginx/sites-enabled /etc/sites 
    3.  

    接下来为我们的网站增加一个conf文件/etc/sites/default.conf,内容如下:

    1. server {  
    2.         listen *:80;  
    3.  
    4.         location / {  
    5.                 root   /var/www/default/pub;  
    6.                 index index.php;  
    7.  
    8.                 # if file exists return it right away  
    9.                 if (-f $request_filename) {  
    10.                         break;  
    11.                 }  
    12.  
    13.                 # otherwise rewrite the fucker  
    14.                 if (!-e $request_filename) {  
    15.                         rewrite ^(.+)$ /index.php$1 last;  
    16.                         break;  
    17.                 }  
    18.  
    19.         }  
    20.  
    21.         # if the request starts with our frontcontroller, pass it on to fastcgi  
    22.         location ~ ^/index.php  
    23.         {  
    24.                 fastcgi_pass 127.0.0.1:9000;  
    25.                 fastcgi_param SCRIPT_FILENAME /var/www/default/pub$fastcgi_script_name;  
    26.                 fastcgi_param PATH_INFO $fastcgi_script_name;  
    27.                 include /usr/local/nginx/conf/fastcgi_params;  
    28.         }  

    上面这个conf文件控制网站的前端风格,其中包括Wordpress,cake等,注意静态内容不是通过FastCGI解析的。另外,你可能需要 修改/var/www/default文件,设置网站文件的默认放置位置。

    启动

    我们的工作结束了,启动看一下效果。

    1. sudo php-fm start  
    2. sudo /etc/init.d/nginx start 

    现在可以测试一下你的网站,看看它工作得如何,如有任何疑问,请随时提出。

    网友留言/评论

    我要留言/评论