Nginx + PHP-FPM + APC=绝妙的组合

本文所介绍的方法应该是目前让PHP(PHP培训 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

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

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

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

  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

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

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

我们也设置了一些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. PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
  12. DAEMON=/usr/local/sbin/nginx
  13. NAME=nginx
  14. DESC=nginx
  15. test -x $DAEMON || exit 0
  16. # Include nginx defaults if available
  17. if [ -f /etc/default/nginx ] ; then
  18. . /etc/default/nginx
  19. fi
  20. set -e
  21. case "$1" in
  22. start)
  23. echo -n "Starting $DESC: "
  24. start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
  25. --exec $DAEMON -- $DAEMON_OPTS
  26. echo "$NAME."
  27. ;;
  28. stop)
  29. echo -n "Stopping $DESC: "
  30. start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
  31. --exec $DAEMON
  32. echo "$NAME."
  33. ;;
  34. restart|force-reload)
  35. echo -n "Restarting $DESC: "
  36. start-stop-daemon --stop --quiet --pidfile \
  37. /usr/local/nginx/logs/$NAME.pid --exec $DAEMON
  38. sleep 1
  39. start-stop-daemon --start --quiet --pidfile \
  40. /usr/local/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
  41. echo "$NAME."
  42. ;;
  43. reload)
  44. echo -n "Reloading $DESC configuration: "
  45. start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
  46. --exec $DAEMON
  47. echo "$NAME."
  48. ;;
  49. *)
  50. N=/etc/init.d/$NAME
  51. echo "Usage: $N {start|stop|restart|force-reload}" >&2
  52. exit 1
  53. ;;
  54. esac
  55. exit 0

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

设置你的网站

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

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

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

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

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

启动

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

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

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

时间: 2024-10-11 11:13:29

Nginx + PHP-FPM + APC=绝妙的组合的相关文章

记录一次自己对nginx+fastcgi(fpm)+mysql压力测试结果

nginx + fastcgi(fpm) 压力测试: CentOS release 5.9 16核12G内存 静态页面: 并发1000,压测200秒,测试结果: 系统最大负载5.47 成功响应: 2563065, 502:0, 失败:0 PHP页面(对mysql进行一次带索引的查询,数据库记录500条): 并发1000,压测200秒,测试结果: 系统最大负载15.66 成功响应: 114368, 502:712, 失败:58715 并发200,压测200秒,测试结果: 系统最大负载25.81 成

深入理解PHP之:Nginx 与 FPM 的工作机制

完全转载(算是一个收藏了) https://zhuanlan.zhihu.com/p/20694204 网络上有很多关于如何配置 Nginx + FPM 的文章,但它们更多从操作的角度出发,告诉我们怎么做,但却没有告诉我们为什么要这么做,本文从 Nginx 与 FPM 的工作机制出发,探讨配置背后的原理,让我们真正理解 Nginx 与 PHP 是如何协同工作的. 要说 Nginx 与 PHP 是如何协同工作的,首先得说 CGI (Common Gateway Interface) 和 FastC

[Nginx] - PHP+FPM相关的配置

CodeIgniter的配置: worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; fastcgi_connect_timeout 300s; fastcgi_send_timeout 300s; fastcgi_read_timeout

nginx和fpm的进程数配置和502,504错误

一般来说 php-cgi进程数不够用.php执行时间长(mysql慢).或者是php-cgi进程死掉,都会出现502错误: Nginx 504 Gateway Time-out则是与nginx.conf的设置有关: 1.502 和 php-fpm.conf 1.request_terminate_timeout引起的资源问题 request_terminate_timeout的值如果设置为0或者过长的时间,可能会引起file_get_contents的资源问题. 如果file_get_conte

nginx+php fpm日志报错信息

recv() failed (104:connect  reset by peer) while reading response header from upstream的原因和解决方案 原因是 php-fpm进程数耗尽了,两个方案: (1). 调整php-fpm.conf里面的pm.max_children,增大,不建议超过300(2). php-fpm.conf里面打开每个对应池的slow日志,根据慢执行日志来优化php代码

linux环境下nginx链接不上fpm

背景: nginx是通过源码安装,php环境和php-fpm是通过apt-get自动安装. 以下记录下出现的几个问题及方法 一.访问php文件无法识别 安装nginx和fpm完成之后,通过在nginx的容器中添加一个php的测试页面为test.php,代码只写 <?phpphpinfo();?> 其中通过页面访问方式如图所示 解决办法: 找到nginx的安装路径,找到nginx.conf,每个人的nginx安装目录位置不一样,我的nginx.conf在/usr/local/nginx/conf

nginx和php-fpm调用方式

一.背景: 在开发中碰到一个问题,项目以nginx+php-fpm形式访问交互,结果访问项目时报错如下图: 二.分析: 提示很明确嘛,去看error.log(在nginx.conf或者vhost里头配置的,找到你对应路径即可) 错误信息如下: 1 2 3 2017/09/18 10:46:21 [error] 3880#0: *92 connect() failed (111: Connection refused)    while connecting to upstream, client

Centos+nginx+uwsgi+Python多站点环境搭建

前言 新公司的第一个项目,服务器端打算用python作为restful api.所以需要在Centos上搭建nginx+fastcgi+python的开发环境,但后面网上很多言论都说uwsgi比fastcgi在很多方面存在优势,推荐用uwsgi而不是fastcgi,详见:http://sunxiunan.com/?p=1778.因此,改为搭建nginx+uwsgi+python这样的技术组合. 正题 步入正题,开始搭建环境.http://www.cnblogs.com/xiongpq/p/338

Nginx模块fastcgi_cache的几个注意点 转

Nginx模块fastcgi_cache的几个注意点 去年年底,我对nginx的fastcgi_cache进行摸索使用.在我的测试过程中,发现一些wiki以及网络上没被提到的注意点,这里分享一下. 在web项目中,大家都已经非常熟悉其架构流程了.都说Cache是万金油,哪里不舒服抹哪里.这些流程中,几乎每个环节都会进行cache.从浏览器到webserver,到cgi程序,到DB数据库,会进行浏览器cache,数据cache,SQL查询的cache等等.对于fastcgi这里的cache,很少被