一、什么是 FastCGI
FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通信的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等,同时,FastCGI也被许多脚本语言所支持,其中就有PHP。
FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器。这在处理高并发访问时,几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少被使用了。
FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。

二、Nginx+FastCGI运行原理
Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket,(这个socket可以是文件socket,也可以是ip socket)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接纳到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端,这就是Nginx+FastCGI的整个运作过程。详细的过程,如图1所示。

图1 Nginx+FastCGI运行原理

三、spawn-fcgi与PHP-FPM

前面介绍过,FastCGI接口方式在脚本解析服务器上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是FastCGI进程管理器,或者称之为FastCGI引擎, spawn-fcgi与PHP-FPM就是支持PHP的两个FastCGI进程管理器。
下面简单介绍spawn-fcgi与PHP-FPM的异同。

spawn-fcgi是HTTP服务器lighttpd的一部分,目前已经独立成为一个项目,一般与lighttpd配合使用来支持PHP,但是ligttpd的spwan-fcgi在高并发访问的时候,会出现内存泄漏甚至自动重启FastCGI的问题。

Nginx是个轻量级的HTTP server,必须借助第三方的FastCGI处理器才可以对PHP进行解析,因此Nginx+spawn-fcgi的组合也可以实现对PHP的解析,这里不过多讲述。

PHP-FPM也是一个第三方的FastCGI进程管理器,它是作为PHP的一个补丁来开发的,在安装的时候也需要和PHP源码一起编译,也就是说PHP-FPM被编译到PHP内核中,因此在处理性能方面更加优秀;同时它在处理高并发方面也比spawn-fcgi引擎好很多,因此,推荐Nginx+PHP/PHP-FPM这个组合对PHP进行解析。

FastCGI 的主要优点是把动态语言和HTTP Server分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求。

四、 PHP与PHP-FPM的安装及优化

1.下载安装包
www.php.net官方网站下载PHP源码包,这里下载的是稳定版php-5.2.13.tar.gz。
http://php-fpm.org/downloads/下载对应的PHP-FPM源码包,这里下载的是php-5.2.13-fpm-0.5.13.diff.gz。
需要注意,在下载软件包版本时,尽量使PHP和PHP-FPM版本一致,如果版本之间相差太大,可以会出现兼容问题。

2.配置安装环境
安装PHP需要下面软件包的支持,如果没有安装,请自行安装。

  1. gcc gcc-c++ libxml2 libxml2-devel autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel  zlib zlib-devel glibc glibc-devel glib2 glib2-devel

由于各个Linux系统版本的不确定性,读者也可以在安装PHP过程中,根据错误提示信息,安装对应的软件库。

3.开始编译安装PHP和PHP-FPM
编译安装PHP和PHP-FPM很简单,下面是安装过程:

  1. [root@localhost local]#tar zxvf php-5.2.13.tar.gz
  2. [root@localhost local]#gzip -cd php-5.2.13-fpm-0.5.13.diff.gz | patch -d php-5.2.13 -p1
  3. [root@localhost local]#cd php-5.2.13
  4. [root@localhost php-5.2.13]#./configure  --prefix=/usr/local/php --enable-fastcgi --enable-fpm
  5. [root@localhost php-5.2.13]#make
  6. [root@localhost php-5.2.13]#make install
  7. [root@localhost php-5.2.13]cp php.ini-dist /usr/local/php/lib/php.ini

其中,第二步将PHP-FPM作为补丁加入PHP源码中。
在“./configure”编译选项中,指定将PHP安装到/usr/local下,“--enable-fastcgi”是启用对PHP的FastCGI支持,“--enable-fpm”是激活对FastCGI模式的fpm支持。
在编译PHP时可以加入很多编译选项,但是这里为了介绍PHP的FastCGI功能没有加入更多的编译选项。

4.配置与优化PHP-FPM
PHP的全局配置文件是php.ini,在上面的步骤中,已经将此文件复制到了/usr/local/php/lib/php.ini下。可以根据每个应用需求的不同,对php.ini进行相应的配置。
下面重点介绍PHP-FPM引擎的配置文件。

根据上面指定的安装路径,PHP-FPM的默认配置文件为/usr/local/php/etc/php-fpm.conf。
php-fpm.conf是一个XML格式的纯文本文件,其内容很容易看明白。这里重点介绍几个重要的配置标签:

标签listen_address是配置fastcgi进程监听的IP地址以及端口,默认是127.0.0.1:9000。
<value name="listen_address">127.0.0.1:9000</value>

标签display_errors用来设置是否显示PHP错误信息,默认是0,不显示错误信息,设置为1可以显示PHP错误信息。
<value name="display_errors">0</value>

标签user和group用于设置运行FastCGI进程的用户和用户组。需要注意的是,这里指定的用户和用户组要和Nginx配置文件中指定的用户和用户组一致。
<value name="user">nobody</value> 
<value name="group">nobody</value>

标签max_children用于设置FastCGI的进程数。根据官方建议,小于2GB内存的服务器,可以只开启64个进程,4GB以上内存的服务器可以开启200个进程。
<value name="max_children">5</value>

标签request_terminate_timeout用于设置FastCGI执行脚本的时间。默认是0s,也就是无限执行下去,可以根据情况对其进行修改。
<value name="request_terminate_timeout">0s</value>

标签rlimit_files用于设置PHP-FPM对打开文件描述符的限制,默认值为1024。这个标签的值必须和Linux内核打开文件数关联起来,例如要将此值设置为65535,就必须在Linux命令行执行'ulimit -HSn 65536'。
<value name="rlimit_files">1024</value>

标签max_requests指明了每个children最多处理多少个请求后便会被关闭,默认的设置是500。
<value name="max_requests">500</value>

标签allowed_clients用于设置允许访问FastCGI进程解析器的IP地址。如果不在这里指定IP地址,Nginx转发过来的PHP解析请求将无法被接受。
<value name="allowed_clients">127.0.0.1</value>

5.管理FastCGI进程
在配置完php-fpm后,就可以启动FastCGI进程了。启动fastcgi进程有两种方式:

  1. /usr/local/php/bin/php-cgi --fpm
  2. 或者
  3. /usr/local/php/sbin/php-fpm  start

建议采用第二种方式启动FastCGI进程。
 /usr/local/php/sbin/php-fpm还有其他参数,具体为start|stop|quit|restart|reload|logrotate。
每个启动参数的含义如下:

  1.  start,启动PHP的FastCGI进程。
  2.  stop,强制终止PHP的FastCGI进程。
  3.  quit,平滑终止PHP的FastCGI进程。
  4.  restart, 重启PHP的FastCGI进程。
  5.  reload, 重新加载PHP的php.ini。
  6.  logrotate, 重新启用log文件。

reload是个很重要的参数,它可以在PHP的FastCGI进程不中断的情况下重新加载改动过的php.ini,因此通过php-fpm可以平滑变更FastCGI模式下的PHP设置。

在FastCGI进程启动后,其监听的IP地址和端口也随即启动,可以通过ps和netstat查看相关信息。

  1. [root@localhost php]# netstat -antl|grep 9000
  2. tcp        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN
  3. [root@localhost php]# ps -ef|grep php-cgi
  4. root      3567     1     0  17:06 ?       00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf
  5. nobody    3568  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf
  6. nobody    3569  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf
  7. nobody    3570  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf
  8. nobody    3571  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf
  9. nobody    3572  3567  0  17:06 ?        00:00:00 /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf
  10. root      3583  3524  0 17:09 pts/1    00:00:00 grep php-cgi

五、配置Nginx来支持PHP
Nginx的安装特别简单,前面已经对此进行了详细介绍,这里不再进行讲述。下面重点介绍Nginx如何通过php-fpm的FastCGI进程对PHP进行解析处理。
由于Nginx本身不会对PHP进行解析,因此要实现Nginx对PHP的支持,其实是将对PHP页面的请求交给fastCGI进程监听的IP地址及端口。如果把php-fpm当做动态应用服务器,那么Nginx其实就是一个反向代理服务器。Nginx通过反向代理功能实现对PHP的解析,这就是Nginx实现PHP动态解析的原理。
这里假定Nginx的安装目录为/usr/local,则Nginx配置文件的路径为/usr/local/nginx/conf/nginx.conf。下面是在Nginx下支持PHP解析的一个虚拟主机配置实例。

  1. server {
  2. include port.conf;
  3. server_name www.ixdba.net ixdba.net;
  4. location / {
  5. index index.html index.php;
  6. root /web/www/www.ixdba.net;
  7. }
  8. location ~ \.php$ {
  9. root           html;
  10. fastcgi_pass   127.0.0.1:9000;
  11. fastcgi_index  index.php;
  12. fastcgi_param  SCRIPT_FILENAME  html$fastcgi_script_name;
  13. include        fastcgi_params;
  14. }
  15. }

通过location指令,将所有以php为后缀的文件都交给127.0.0.1:9000来处理,而这里的IP地址和端口就是FastCGI进程监听的IP地址和端口。
fastcgi_param指令指定放置PHP动态程序的主目录,也就是$fastcgi_script_name前面指定的路径,这里是/usr/local/nginx/html目录,建议将这个目录与Nginx虚拟主机指定的根目录保持一致,当然也可以不一致。
fastcgi_params文件是FastCGI进程的一个参数配置文件,在安装Nginx后,会默认生成一个这样的文件,这里通过include指令将FastCGI参数配置文件包含了进来。
接下来,启动nginx服务。
/usr/local/nginx/sbin/nginx
到此为止,Nginx+PHP已经配置完成。

六、测试Nginx对PHP的解析功能
这里在/usr/local/nginx/html目录下创建一个phpinfo.php文件,内容如下:
<?php phpinfo(); ?>
然后通过浏览器访问http://www.ixdba.net/index.html,默认会在浏览器显示“Welcome to Nginx!”表示Nginx正常运行。
接着在浏览器中访问http://www.ixdba.net/phpinfo.php,如果PHP能够正常解析,会出现PHP安装配置以及功能列表统计信息。

七、实例讲解Nginx中FastCGI参数的优化
在配置完成Nginx+FastCGI之后,为了保证Nginx下PHP环境的高速稳定运行,需要添加一些FastCGI优化指令。下面给出一个优化实例,将下面代码添加到Nginx主配置文件中的HTTP层级。

  1. fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
  2. fastcgi_connect_timeout 300;
  3. fastcgi_send_timeout 300;
  4. fastcgi_read_timeout 300;
  5. fastcgi_buffer_size 64k;
  6. fastcgi_buffers 4 64k;
  7. fastcgi_busy_buffers_size 128k;
  8. fastcgi_temp_file_write_size 128k;
  9. fastcgi_cache TEST;
  10. fastcgi_cache_valid 200 302 1h;
  11. fastcgi_cache_valid 301 1d;
  12. fastcgi_cache_valid any 1m;

下面是对上述代码的含义进行介绍。
第一行代码是为FastCGI缓存指定一个文件路径、目录结构等级、关键字区域存储时间和非活动删除时间。
fastcgi_connect_timeout指定连接到后端FastCGI的超时时间。
fastcgi_send_timeout指定向FastCGI传送请求的超时时间,这个值是已经完成两次握手后向FastCGI传送请求的超时时间。
fastcgi_read_timeout指定接收FastCGI应答的超时时间,这个值是已经完成两次握手后接收FastCGI应答的超时时间。

fastcgi_buffer_size用于指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers选项指定的缓冲区大小。

fastcgi_buffers指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求。如果一个PHP脚本所产生的页面大小为256KB,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于硬盘。一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“16 16k”、“4 64k”等。

fastcgi_busy_buffers_size的默认值是fastcgi_buffers的两倍。

fastcgi_temp_file_write_size表示在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍。

fastcgi_cache表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生,但是开启缓存也会引起很多问题,要视具体情况而定。
fastcgi_cache_valid、fastcgi用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一个小时,将301应答缓存1天,其他应答均缓存1分钟。

实战Nginx与PHP(FastCGI)的安装、配置与优化的更多相关文章

  1. linux下nginx、php和mysql安装配置

    一.安装nginx 安装nginx yum install -y epel-release yum install nginx -y 查看nginx软件包包括了哪些文件 rpm -ql nginx 启 ...

  2. FastDFS分布式文件系统&Nginx负载均衡最小环境安装配置[超级详解]

    1.背景 FastDFS 是一款开源的.分布式文件系统(Distributed File System),由淘宝开发平台部资深架构师余庆开发.该开源项目的主页是 http://code.google. ...

  3. RabbitMQ3 单机及集群安装配置及优化

    一.操作系统需求及配置 # 1.1.操作系统推荐配置 4C*8G*40G磁盘 # 1.2.内核参数优化 # 系统参数需要留有swap空间,rabbitmq 启动进程用户打开文件数至少需要5万,yum安 ...

  4. Linux下 nginx + 最新版php5.5 安装配置详解

    1.nginx的安装: 首先nginx的安装需要依赖最基础的三个包,这里面我们不设计更多的扩展模块,只是安装最基础的三个包, zlib 此包主要是对http内容进行gzip压缩,减少网络传输流量 PC ...

  5. nginx反向代理架构与安装配置(一)

    这里我们准备四台虚拟机,二台负载均衡(LB01,LB02),二台web服务器(WEB01,WEB02).   这里默认所有软件都安装在/data目录下.   四台虚拟机的初始安装是centos7的最小 ...

  6. nginx 多级7层代理安装配置

    编译安装 yum install zlib-devel -y wget https://nginx.org/download/nginx-1.15.12.tar.gz tar -zxf nginx-1 ...

  7. nginx访问不了zabbix安装配置界面

    通过yum安装的php等其他各种软件,配置好后,html目录下面php可以解析,但是就是访问不到setup.php文件.后来各种查找,发现是setup解析错误 PHP Parse error:  sy ...

  8. Nginx技术研究系列3-OpenResty安装配置

    上两篇中介绍了: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 Ngnix技术研究系列2-基于Redis实现动态路由 发现,应该加一篇OpenResty的安装部署说明,方便大家按图索骥 ...

  9. nginx安装配置+清缓存模块安装

    经过一段时间的使用,发现nginx在并发与负载能力方面确实优于apache,现在已经将大部分站点从apache转到了nginx了.以下是nginx的一些简单的安装配置. 环境 操作系统:CentOS. ...

  10. nginx 安装配置+清缓存模块安装

    经过一段时间的使用,发现 nginx 在并发与负载能力方面确实优于 apache,现在已经将大部分站点从 apache 转到了 nginx 了.以下是 nginx 的一些简单的安装配置.环境操作系统: ...

随机推荐

  1. 小结一下前段时间做的rpgdemo

    虽然说已经是彻底放弃继续做那个demo了(代码结构混乱,想增加新功能非常的不方便),不过还是花了一点心血在里面的,毕竟这是我开始学习unity游戏制作的初衷,不过果然是学的越多越发现自己的不足... ...

  2. 【PC端】jQuery+PHP实现浏览更多内容(jquery.more.js插件)

    参数说明: 'amount' : '10', //每次显示记录数 'address' : 'comments.php', //请求后台的地址 'format' : 'json', //数据传输格式 ' ...

  3. Bar codes in NetSuite Saved Searches(transport/reprint)

    THIS IS A COPY FROM BLOG Ways of incorporating Bar Codes into your Netsuite Saved Searches.    Code ...

  4. 微信touchmove不生效

    最近在写一个微信里面滑动切换图片的功能,发现在chrome下都正常显示,可是在微信和qq浏览器里面就是不行. 经过一番排查,发现了问题: touchmove只触发了一次. 解决方案: 在touchst ...

  5. Mac下遇到 'reading initial communication packet’ 问题

    今天在开发过程中,一个单位跑的好好的项目,在家中的Mac下运行时,遇到了下面这个错误:   "Lost connection to MySQL server at 'reading init ...

  6. ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。

    问题:ObjectStateManager 中已存在具有同一键的对象.ObjectStateManager 无法跟踪具有相同键的多个对象. 解决方案:在查询的时候加上AsNoTracking()就ok ...

  7. 事件委托和JQ事件绑定总结

    事件委托: 比喻:事件委托的事例在现实当中比比皆是.比如,有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三个人在公司门口等快递:二是委托给前台MM代为签收.现实当中,我们大都采用委托的方 ...

  8. Git_1基础操作,从安装到提交完成(windows)

    github地址:https://github.com/zhangsai521314/Git 1:安装Git Bash(https://git-scm.com/),安装一路NEXT. 2:目录架构: ...

  9. Linux环境部署(JDK/Tomcat/MySQL/证书)

    #################### 安装JDK1.7.x ####################下载JDK1.7版本的tar包(http://www.oracle.com/technetwor ...

  10. mac 下jetbrains IDE系列IDE主题

    1.直接粘贴导入 使用shift+command+g键进入: ~/Library/Preferences/ 在下边找到当前的IED(WebStrom.IdealIC.PyCharm) 然后在下边找到c ...