nginx_笔记分享_php-fpm详解

参考

http://syre.blogbus.com/logs/20092011.html
http://www.mike.org.cn/articles/what-is-cgi-fastcgi-php-fpm-spawn-fcgi/
http://www.larro.cn/?p=35

nginx php php-fpm  cgi fastcgi  等等它们之间的关系让人糊涂,google一天发现有不少介绍的好文章,不过都是各说各的不免让人抓狂,特此将上面几位前辈的文章重新整理了一下,本着拿 来主义思想(汗),照搬了原作者的部分文章,并加入了自己的想法,思路清晰了不少,再次感谢前辈无私奉献!!

Nginx 为什么要通过Fastcgi来解析PHP

一般,web server对PHP的支持方式有这么三种:
通过web server内置的模块来实现,比如Apache的mod_php模块 ,但是Nginx没有这种模块。
通过CGI方式,该种方式的缺点是性能差,因为每次服务器遇到这些脚本都需要重新启动脚本解析器来执行脚本然后将结果返回给服务器;另一方面就是不太安全;该方发几乎很少使用了。
FastCGI,FastCGI就是对CGI的改进,一般采用C/S结构,一般脚本处理器会启动一个或者多个daemon进程,每次Nginx遇到php脚本的时候,直接交付给FastCGI的进程来执行,然后将得到的结果返回给浏览器。

什么是 CGI

全称是”公共网关接口”(Common Gateway Interface),web server与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在web server上。 
CGI可以用任何一种语言编写, 只要这种语言具有标准输入、输出和环境变量,如php,perl,tcl等。

什么是 FastCGI

FastCGI 是一个可伸缩、高速的在web server和脚本语言间通迅的接口。
FastCGI 被许多脚本语言所支持,包括 php,如果用 --enable-fastcgi 选项编译的话。 
多数流行的web server都支持 FastCGI,包括Apache(mod_fastcgi和mod_fcgid),Zeus,nginx和lighttpd。 
FastCGI 的主要优点是把动态语言和 web server 分离开来。这种技术允许 web server 和动态语言运行在不同的主机上。这可以改进可扩展性和安全性而没有大的效率损失。

php-fpm 可以和任何支持外部 FastCGI 技术的 web server 一起使用(比如Nginx)。

举个列子 
比如我有一台LNMP(nginx mysql php)服务器负载很高,现在又有了三个服务器 ,将原本的LNMP  现在分拆成三台服务器,按应用分成了三部分,当然了这里没有考虑成本,不过在结合虚拟化技的情况下,按应用分拆的好处是非常大的,除了可以给web ,db 做负载均衡与高可用是不是某天我们的php-fpm 也可以LB与HA?


www1 web server   NGINX
php1 php_script server   PHP(php-fpm)
db1  mysql server   MYSQL

PHP-FPM、Spawn-FCGI php-cgi都是fastcgi管理器。

什么是PHP-CGI

PHP-CGI是PHP自带的FastCGI管理器
启动PHP-CGI,使用如下命令:
php-cgi -b 127.0.0.1:9000
PHP-CGI的不足
1、php-cgi变更php.ini配置后需重启php-cgi才能让新的php-ini生效,不可以平滑重启
2、直接杀死php-cgi进程,php就不能运行了。(PHP-FPM和Spawn-FCGI就没有这个问题,守护进程会平滑从新生成新的子进程。)

什么是Spawn-FCGI

Spawn-FCGI是一个通用的FastCGI管理服务器, 它是lighttpd中的一部份,很多人都用Lighttpd的Spawn- FCGI进行FastCGI模式下的管理工作,不过有不少缺点。而PHP-FPM的出现多少缓解了一些问题,但PHP-FPM有个缺点就是要重新编译,这 对于一些已经运行的环境可能有不小的风险(refer),不过在php 5.3.*中可以直接使用PHP-FPM了。
Spawn-FCGI目前已经独成为一个项目,更加稳定一些,也给很多Web 站点的配置带来便利。已经有不少站点将它与nginx搭配来解决动态网页。

什么是 PHP-FPM

PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中,必须将它patch到你的PHP源代码中,在编译安装PHP后才可以使用。 
PHP5.3.* 中已经集成php-fpm了,不再是第三方的包了,PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比 spawn-fcgi具有更多优点,所以被PHP官方收录了,在./configure的时候带 --enable-fpm参数即可开启PHP-FPM

下面是关于启用 FastCGI SAPI 时的问题和 php-fpm 是如何解决他们的对比列表。

描述 php自带的 spawn-fcgi + spawn-php.sh + daemontools php-fpm
php守护进程化: pid file, log file, setsid(), setuid(), setgid(), chroot() (-) (+) (+)
进程管理。可以用 "graceful" 来停止并启动 php worker 进程而不会丢失请求。能够平滑地升级配置和二进制程序而不丢失任何请求。 php4 (-), php5 (只有 graceful) (-) (+)
严格限制来源请求的 web server 的 ip 地址 php4 (-) php5 (+) (从 5.2.2 开始) (-) (+)
根据负载动态调整进程数 (-) (-) Todo
用不同的 uid/gid/chroot/environment 和不同的 php.ini 选项启动 worder 进程。你不需要 safe mode 了! (-) (-) (+)
记录 worker 进程 stdout 和 stderr 日志 (-) (-) (+)
如果使用优化器,在共享内存意外破坏的情况下紧急重启所有的进程 (-) (-) (+)
如果 set_time_limit() 失败,确保进程会结束 (-) (-) (+)
特色功能 Error header、优化的上传支持、fastcgi_finish_request()


至此 我已经明白了它们之间的关系了!!!

下面是php-fpm的进一步介绍!!

特色功能
所有这些特性都是“不打断”的方式实现的。也就是说,如果你不使用它们,它们的存在不会影响php的功能性——他们都是“透明”的。 
Error header
范围:php.ini 选项 
分类:便利性 
默认情况下,如果被访问的php脚本包含语法错误,用户会收到一个空的“200 ok”页。这是不方便的。Error header 这个 php.ini 选项允许在这种情况下产生一个 HTTP 错误码,比如“HTTP/1.0 550 Server Made Big Boo”,从而中断web server请求并显示一个正确的错误页。 
如果要实现这样的功能,需要在 php.ini 中添加一条 fastcgi.error_header = "HTTP/1.0 550 Server Made Big Boo" 
在 php-5.2.4 中添加了类似,但不相同的功能:如果被访问的php脚本包含语法错误,并且 display_errors = off,会立刻返回“HTTP/1.0 500 Internal Server Error”。 
如果你需要设定一个 503 错误,或者想要使这个行为独立于 display_errors 的设置,那么可以使用fastcgi.error_header。如果你在 php-5.2.5 或以上版本上启用 php-fpm,那么 fastcgi.error_header的优先级更高。 
优化的上传支持
实质:web server 支持
类型:优化
这个特性正如名字那样,可以加速对大 POST 请求的处理速度,包括文件上传。优化是通过将请求体已写入一个临时文件,然后 fastcgi 协议传递文件名而不是请求体到来实现的。目前就我所知,只有 nginx0.5.9 以上才支持这个功能。显然,这种模式只在 php 和 web server 在一台机器上的时候才能用。
nginx 样例配置:
location ~ \.php$ { 
    fastcgi_pass_request_body off; 
    client_body_in_file_only clean; 
    fastcgi_param  REQUEST_BODY_FILE  $request_body_file; 
    ... 
    fastcgi_pass ...; 
}
在php中不需要配置任何东西。如果php收到了参数REQUEST_BODY_FILE,就读取其中的请求体,如果没有,就自行从fastcgi协议中读取请求体。
结合这个特性,可以考虑对临时文件使用内存文件系统,例如tmpfs(linux):
client_body_temp_path /dev/shm/client_body_temp;
fastcgi_finish_request()
范围:php 函数
类型:优化
这个特性可以提高一些 php 请求的处理速度。如果有些处理可以在页面生成完后进行,就可以使用这种优化。比如,在 memcached 中保存 session 就可以在页面交给 web server 后进行。fastcgi_finisth_request() ,这一特性可以结束响应输出,web server 可以立即开始交给等不及的客户端,而此刻,php 可以在请求的上下文环境中处理许多事情。比如保存session,转换上传的视频,处理统计等等。
fastcgi_finisth_request() 会触发 shutdown 函数运行。
request_slowlog_timeout
范围: php-fpm.conf 选项 
分类: 方便 
这个选项能让你跟踪执行缓慢的脚本并把他们连同调用栈一起记录再日志文件中。例如如下设置: 
<value name="request_slowlog_timeout">5s</value>
<value name="slowlog">logs/slow.log</value>
记录的 slow.log 可能是这个样子: 
Sep 21 16:22:19.399162 pid 29715 (pool default)
script_filename = /local/www/stable/www/catalogue.php 
[0x00007fff23618120] mysql_query() /srv/stable/common/Database/class.MySQLRequest.php:20 
[0x00007fff23618560] getResult() /srv/stable/common/Database/class.Facade.php:106 
[0x00007fff23618aa0] query() /srv/stable/common/mysite.com/ORM/class.UsersMapper.php:99 
[0x00007fff23618d60] resolveByID() /srv/stable/common/mysite.com/ORM/class.User.php:629 
[0x00007fff236193b0] getData() /srv/stable/common/class.DataEntity.php:90
[0x00007fff236195d0] load() /srv/stable/common/mysite.com/ORM/class.User.php:587 
[0x00007fff23619a00] getIsHidden() /srv/stable/common/mysite.com/class.User.php:42 
[0x00007fff2361a470] getName() /local/www/stable/www/catalogue.php:41
同时,在 error.log 中保存了如下记录: 
Sep 21 16:22:19.399031 [WARNING] fpm_request_check_timed_out(), line 135: child 29715, script ‘/local/www/stable/www/catalogue.php‘ (pool default) executing too slow (5.018002 sec), logging
正如你再例子中看到的,脚本运行了 5 秒以上,并很可能是由于 mysql 响应慢造成的(top backtrace)。 
FAQ
Q:php-fpm 可以和 ZendOptimize 一起用吗?
A:完全可以。

Q:php-fpm 可以和 ZendPlatform、xcache、eAccelerator、APC 等的优化器一起用吗?
A:是的。php-fpm 的架构和任何一种用于高速 opcode 缓存的共享内存都适用。唯一的限制是:所有的 worker 进程只能适用一个缓存,即使它们用不同的 uid/gid 运行
Q:为什么我要给 php 打补丁呢?spawn-fcgi 不需要这样!
A:php-fpm 的创建是为了增强方便管理。没有打过补丁的 php 不能做到: 
平滑重启 php 而不丢失请求,包括升级 php 二进制文件 以及/或者 扩展。 
用不同的 uid / gid / chroot 环境运行 worker 进程 
所有的设置只有一个配置文件 
根据负载动态请求 (TODO) 
对 php 请求实时统计性能 (TODO)
Q:为什么要用 root 运行 php-fpm 呢?这安全吗?
A:用 root 启动 php-fpm 只有在你打算用不同 uid/gid 的 php 来处理请求时才有意义。比如,在共享主机上的不同站点,因为只有在 master 进程用 root 运行的时候,才可以建立不同uid/gid 的子进程,这是相当安全的,master 进程自己从来不会去处理请求,在任何情况下,php-fpm 都不会用 root 身份来处理请求。

Q:php-fpm 可以加速 php 脚本处理速度吗?
A:不,它不会影响处理速度,不过如果你使用一些特殊特性,对于一些特定的请求还是可以有性能提升的。

Q:如果我把我的网站从 mod_php 迁移到 php-fpm ,我会得到性能提升吗?
A: 通常,当有服务器上有大量空闲内存可用时,能从迁移到 php-fpm 中得到的性能提升可能不大,但是如果内存并不充裕,性能提升还是很可观的,在某些情况下可以达到 300-500%。这可能是由于 nginx + php-fpm 一般会比 Apache + mod_php 使用更少的内存。而且 VFS 缓存会由于更多的空余内存而更有效地工作。

Q:php-fpm 将来会被官方的 php 包含吗?
A: 我希望如此。目前,php-fpm 代码的协议是 GPL 。所以现在 php-fpm 的代码与 php 协议(类似 bsd)并不匹配。这是临时性措施。这样的选择是为了简化开发过程。一旦代码的功能完备,比如自适应生成子进程和其他一些东西,协议会改为一个相匹配的。 之后,php-fpm 会正式发布给 php 开发团队,并被建议包含。
邮件列表
如果你有问题的话,请不要犹豫在邮件组里写邮件。 
English: highload-php-en Russian: highload-php-ru
文档
php-fpm 已经在 Linux、MacOSX、Solaris 和 FreeBSD 上测试通过。 
确信 libxml2(在某些系统上叫做libxml2-devel)已经安装。 
下载最小的 php 和 php-fpm 
$ bzip2 -cd php-5.2.5.tar.bz2 | tar xf -
$ gzip -cd php-5.2.5-fpm-0.5.7.diff.gz | patch -d php-5.2.5 -p1
$ cd php-5.2.5 && ./configure --enable-fastcgi --enable-fpm
$ make all install
编辑 $prefix/etc/php-fpm.conf 
运行 $prefix/bin/php-cgi --fpm 
仔细检查 $prefix/logs/php-fpm.log 
运行 phpinfo() 检查你的网站是否还正常运行 
master 进程的 pid 被存放在 $prefix/logs/php-fpm.pid
master进程可以理解以下信号:
SIGINT, SIGTERM 
立刻终止 
SIGQUIT 
平滑终止 
SIGUSR1 
重新打开日志文件 
SIGUSR2 
平滑重载所有worker进程并重新载入配置和二进制模

向php-fpm作者致敬
 
关于
嗨,我的名字叫 Andrei Nigmatulin, 我是 php-fpm 的作者。 
从 2004 年开始,我就在等有什么人让 PHP FastCGI 能满足产品环境,但我等不下去了。 
php-fpm 是在数个项目种使用 PHP 的 FastCGI SAPI 中的知识、经验和想法的产物。 
php-fpm 可以在 GPL 协议下用在公共用途。和 php-fpm 绑定的修改版的 libevent 是在 BSD 协议下发布的。 
我需要得到您的反馈——新的想法和建议——来改进和优化 php FastCGI SAPI。 如果您有什么想法、意见、补充和建议,我会很高兴,很原意听取,也许还会实现他们。给给我发邮件吧。(地址在本页的末尾)。 
如果你想支持 php-fpm 的开发,可以作一些捐赠: Paypal Yandex.Money 
 
15/05/2007 - 第一次提交到 php-fpm. 
andrei dot nigmatulin at gmail dot com

译注:
php-fpm还带有一个更方便的脚本,在$prefix/sbin/php-fpm。可以用php-fpm start|graceful|restart|stop来维护。稍编辑一下就可以让它使用配置文件。

时间: 2024-11-11 03:48:50

nginx_笔记分享_php-fpm详解的相关文章

hadoop 学习笔记:mapreduce框架详解

hadoop 学习笔记:mapreduce框架详解 开始聊mapreduce,mapreduce是hadoop的计算框架,我 学hadoop是从hive开始入手,再到hdfs,当我学习hdfs时候,就感觉到hdfs和mapreduce关系的紧密.这个可能是我做技术研究的 思路有关,我开始学习某一套技术总是想着这套技术到底能干什么,只有当我真正理解了这套技术解决了什么问题时候,我后续的学习就能逐步的加快,而学习 hdfs时候我就发现,要理解hadoop框架的意义,hdfs和mapreduce是密不

iOS 6分享列表——UIActivityViewController详解

iOS 6分享列表——UIActivityViewController详解 2013-06-03 01:42:33     发表评论 在iOS 6之后提供了一个分享列表视图,它通过UIActivityViewController管理.苹果设计它主要的目的是替换分享动作选单(ActionSheet),分享动作选单是出于分享目的的动作选单. 通过动作选单上的选择按钮,可以把图片分享给别人.但是随着iOS功能的不断增加,需要分享的内容越来越多,它会以模态视图方式呈现.iPad设备的分享列表,它会以Po

笔记整理--HTTP Header 详解

HTTP Header 详解 2013/09/21 | 分类: IT技术 | 0 条评论 | 标签: HTTP 分享到:36 原文出处: zcmhi HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用了请求/响应模型,浏览器或其他客户端发出请求,服务器给与响应.就整个网络资源传输而言,包括message-header和message-body两部分.首先传递message- header,即http header消息.htt

Linux学习笔记——用户及权限详解

用户及权限详解    用户.组.权限 安全上下文(secure context): 权限: r   w   x  文件: r:可读,可以使用类似cat等命令查看文件内容: w:可写,可以编辑或删除此文件: X:可执行,exacutable,可以命令提示符下当作命令提交给内核运行:  目录: r:可以对此目录执行ls以列出内部的所有文件: w:可以在此目录创建文件: x:可以使用cd切换进此目录,也可以使用ls -l查看内部文件的详细信息: rwx: r--:只读 r-x:读和执行 ---:无权限

CSS学习笔记(9)--详解CSS中:nth-child的用法

详解CSS中:nth-child的用法 前端的哥们想必都接触过css中一个神奇的玩意,可以轻松选取你想要的标签并给与修改添加样式,是不是很给力,它就是":nth-child". 下面我将用几个典型的实例来给大家讲解:nth-child的实际用途: Tips:还用低版本的IE浏览器的哥们请绕过! :nth-child(2)选取第几个标签,"2可以是你想要的数字" .demo01 li:nth-child(2){background:#090} :nth-child(n

【笔记——Hibernate】Hibernate详解

Hibernate 三大框架之一,他的任务是和数据库打交道,以下是我对它的认识,以及详解. 注意:以下的介绍是针对 hibernate-release-4.3.7.Final 的. 目录解析: hibernate-release-4.3.7.Final -documentation 里面都是些文档 -devguide 开发指南 -javadocs api -manual 几乎所有的介绍都在里面了 -quickstart  简单的介绍以下Hibernate的用法功能 -topical 类似其他介绍

Linux学习笔记—— 用户管理命令详解

 用户管理命令详解  用户管理: useradd,userdel,usermod,passwd,chsh,chfn,finger,id,chage 添加用户: useradd [options] USERNAME    -u (UID)   手动指定UID -g (GID)  (基本组) -G, ...     (附加组) 可以有多个,彼此之间用,号隔开 -c "COMMENT"         注释信息     -d /path/to/somedirectory  指定家目录 -s

[学习笔记]struts.xml配置详解(所有基本配置,包括通配符)

1.<include> 利用include标签,可以将一个struts.xml配置文件分割成多个配置文件,然后在struts.xml中使用<include>标签引入其他配置文件.比如一个网上购物程序,可以把用户配置.商品配置.订单配置分别放在3个配置文件user.xml.goods.xml和order.xml中,然后在struts.xml中将这3个配置文件引入: struts.xml: [html] view plaincopy <?xml version="1.0

【Java学习笔记之三十三】详解Java中try,catch,finally的用法及分析

这一篇我们将会介绍java中try,catch,finally的用法 以下先给出try,catch用法: try { //需要被检测的异常代码 } catch(Exception e) { //异常处理,即处理异常代码 } 代码区如果有错误,就会返回所写异常的处理. 首先要清楚,如果没有try的话,出现异常会导致程序崩溃.而try则可以保证程序的正常运行下去,比如说: try { int i = 1/0; } catch(Exception e) { ........ } 一个计算的话,如果除数

Maven笔记 pom.xml配置详解

pom.xml文件配置详解 --声明规范 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quo