本文所介绍的方法应该是目前让PHP最快的办法:Nginx + PHP-FPM + APC。我们将从安装Nginx http服务器、PHP和PHP-FPM补丁,以及APC,详细的讲解这种方法的具体配置及应用,最终的效果如何?相信会让你大吃一惊。
相关文章推荐:Nginx http服务相关的配置文件 Nginx+PHP配置相关进程的简要介绍
背景
过去两年多来,我们的网站一直运行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,第一件事情是安装所有的依赖包。
- sudo apt-get install make bison flex gcc patch autoconf subversion locate
- 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
准备好依赖包之后,我们就可以开始。
编译PHP
我们下载的是PHP 5.2.8源代码包,还有对应的PHP-FPM补丁,我们先打上补丁,然后再编译。
- cd /usr/local/src/
- sudo wget http://us.php.net/get/php-5.2.8.tar.gz/from/this/mirror
- sudo tar zvxf php-5.2.8.tar.gz
- sudo wget http://php-fpm.anight.org/downloads/head/php-5.2.8-fpm-0.5.10.diff.gz
- sudo gzip -cd php-5.2.8-fpm-0.5.10.diff.gz | sudo patch -d php-5.2.8 -p1
- cd php-5.2.8
- 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
- sudo make all install
- sudo strip /usr/local/bin/php-cgi
如果在运行上面命令时遇到错误,很可能是因为缺少依赖包造成的。另外,确保你正确启用和禁用了特定的PHP配置选项。紧接着我们通过PECL安装一些将会用到的模块:
- sudo pecl install memcache
- sudo pecl install apc
- sudo pecl install syck-beta
在安装apc模块时,请务必关闭Apache选项,如果你没有关闭,它也会提醒你。接下来复制我们常用的php.ini:
- sudo cp /usr/local/src/php-5.2.8/php.ini-recommended /usr/local/lib/php.ini
最后,我们建立符号链接:
- sudo mkdir /etc/php/
- sudo ln -s /usr/local/lib/php.ini /etc/php/php.ini
- 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行。
- <value name=”owner”>www-data</value>
- <value name=”group”>www-data</value>
- <value name=”user”>www-data</value>
- <value name=”group”>www-data</value>
Nginx
和编译PHP一样非常简单:
- cd ..
- sudo wget http://sysoev.ru/nginx/nginx-0.6.35.tar.gz
- sudo tar zxvf nginx-0.6.35.tar.gz
- sudo rm -f nginx-0.6.35.tar.gz
- cd nginx-0.6.35
- 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
- sudo make && sudo make install
再创建一个链接:
- sudo ln -s /usr/local/nginx/conf /etc/nginx
下一步是可有可无的,但我一直使用至今,说说也无妨。打开/etc/nginx/nginx.conf,最终修改结果如下:
- user www-data;
- worker_processes 6;
- events {
- worker_connections 1024;
- }
- http {
- include mime.types;
- default_type application/octet-stream;
- sendfile on;
- keepalive_timeout 10 10;
- gzip on;
- gzip_comp_level 1;
- gzip_proxied any;
- gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
- log_format main ‘$remote_addr – $remote_user [$time_local] ‘
- ‘”$request” $status $body_bytes_sent “$http_referer” ‘
- ‘”$http_user_agent” “$http_x_forwarded_for”‘;
- access_log /var/log/nginx_access.log main;
- error_log /var/log/nginx_error.log debug;
- include /usr/local/nginx/sites-enabled/*;
- }
我们也设置了一些FastCGI参数,让PHP不会噎着,也可以避免Nginx 503错误,打开/etc/nginx/fastcgi_params,添加以下参数:
- fastcgi_connect_timeout 60;
- fastcgi_send_timeout 180;
- fastcgi_read_timeout 180;
- fastcgi_buffer_size 128k;
- fastcgi_buffers 4 256k;
- fastcgi_busy_buffers_size 256k;
- fastcgi_temp_file_write_size 256k;
- fastcgi_intercept_errors on;
最后,我们创建一个SystemV风格的启动脚本,保存为/etc/init.d/nginx。
- #! /bin/sh
- ### BEGIN INIT INFO
- # Provides: nginx
- # Required-Start: $all
- # Required-Stop: $all
- # Default-Start: 2 3 4 5
- # Default-Stop: 0 1 6
- # Short-Description: starts the nginx web server
- # Description: starts nginx using start-stop-daemon
- ### END INIT INFO
- PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
- DAEMON=/usr/local/sbin/nginx
- NAME=nginx
- DESC=nginx
- test -x $DAEMON || exit 0
- # Include nginx defaults if available
- if [ -f /etc/default/nginx ] ; then
- . /etc/default/nginx
- fi
- set -e
- case “$1” in
- start)
- echo -n “Starting $DESC: “
- start-stop-daemon –start –quiet –pidfile /usr/local/nginx/logs/$NAME.pid \
- –exec $DAEMON — $DAEMON_OPTS
- echo “$NAME.”
- ;;
- stop)
- echo -n “Stopping $DESC: “
- start-stop-daemon –stop –quiet –pidfile /usr/local/nginx/logs/$NAME.pid \
- –exec $DAEMON
- echo “$NAME.”
- ;;
- restart|force-reload)
- echo -n “Restarting $DESC: “
- start-stop-daemon –stop –quiet –pidfile \
- /usr/local/nginx/logs/$NAME.pid –exec $DAEMON
- sleep 1
- start-stop-daemon –start –quiet –pidfile \
- /usr/local/nginx/logs/$NAME.pid –exec $DAEMON — $DAEMON_OPTS
- echo “$NAME.”
- ;;
- reload)
- echo -n “Reloading $DESC configuration: “
- start-stop-daemon –stop –signal HUP –quiet –pidfile /usr/local/nginx/logs/$NAME.pid \
- –exec $DAEMON
- echo “$NAME.”
- ;;
- *)
- N=/etc/init.d/$NAME
- echo “Usage: $N {start|stop|restart|force-reload}” >&2
- exit 1
- ;;
- esac
- exit 0
不要忘了设置可执行权限。
设置你的网站
这一阶段的工作主要按你自己的习惯完成,这里仅做一个粗略的介绍。首先我们创建一个目录来存放我们的网站配置文件:
- sudo mkdir /usr/local/nginx/sites-enabled
- sudo ln -s /usr/local/nginx/sites-enabled /etc/sites
接下来为我们的网站增加一个conf文件/etc/sites/default.conf,内容如下:
- server {
- listen *:80;
- location / {
- root /var/www/default/pub;
- index index.php;
- # if file exists return it right away
- if (-f $request_filename) {
- break;
- }
- # otherwise rewrite the fucker
- if (!-e $request_filename) {
- rewrite ^(.+)$ /index.php$1 last;
- break;
- }
- }
- # if the request starts with our frontcontroller, pass it on to fastcgi
- location ~ ^/index.php
- {
- fastcgi_pass 127.0.0.1:9000;
- fastcgi_param SCRIPT_FILENAME /var/www/default/pub$fastcgi_script_name;
- fastcgi_param PATH_INFO $fastcgi_script_name;
- include /usr/local/nginx/conf/fastcgi_params;
- }
- }
上面这个conf文件控制网站的前端风格,其中包括Wordpress,cake等,注意静态内容不是通过FastCGI解析的。另外,你可能需要修改/var/www/default文件,设置网站文件的默认放置位置。
启动
我们的工作结束了,启动看一下效果。
- sudo php-fm start
- sudo /etc/init.d/nginx start
现在可以测试一下你的网站,看看它工作得如何,如有任何疑问,请随时提出。