[转]php-fpm配置具体解释
[转]php-fpm配置具体解释
php-fpm具体解释
原文链接:http://php-fpm.anight.org/
wiki:http://www.php-fpm.com/
翻译:http://syre.blogbus.com/logs/20092011.html
什么是 FastCGI
FastCGI 是一个可伸缩、快速的在web server和脚本语言间通迅的接口。关于FastCGI技术的很多其它信息能够在官方站点和Wikipedia看到。
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 一起使用。
php-fpm是做啥用的
非常不幸,官方站点 php.net 上的 php 在将 FastCGI SAPI 用于生产环境方面有很多已知的问题。
以下是关于启用 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的功能性——他们都是“透明”的。
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 样例配置:
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 选项
分类: 方便
这个选项能让你跟踪执行缓慢的脚本并把他们连同调用栈一起记录再日志文件里。
比如例如以下设置:
记录的 slow.log 可能是这个样子:
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 中保存了例如以下记录:
正如你再样例中看到的。脚本执行了 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)已经安装。
$ 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
编辑
执行
细致检查
执行 phpinfo() 检查你的站点是否还正常执行
master 进程的 pid 被存放在
master进程能够理解以下信号:
SIGINT, SIGTERM | 立马终止 |
SIGQUIT | 平滑终止 |
SIGUSR1 | 又一次打开日志文件 |
SIGUSR2 | 平滑重载全部worker进程并又一次加载配置和二进制 |
关于
嗨。我的名字叫 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来维护。稍编辑一下就能够让它使用配置文件。
后记:
最開始,php-fpm 仅仅有俄文文档,弄的我非常郁闷。于是我先用 google 翻译先弄成英文。然后再人工翻成中文。这其中会难免会在我自己的英文水平引起的错误之外,再多些错误出来。
后来最终有了一个英文的 wiki。并邀请我提供中文翻译。
同一时候,距上一次翻译(2008年5月)以后。原来的文档也已经有了更新。于是我就依据英文 wiki ,又一次翻译了一遍。
php-fpm 启动參数及重要配置具体解释
约定几个文件夹
- /usr/local/php/sbin/php-fpm
- /usr/local/php/etc/php-fpm.conf
- /usr/local/php/etc/php.ini
一,php-fpm的启动參数
1 2 3 4 5 6 7 8 9 10 11 12 13 | #測试php-fpm配置 /usr/local/php/sbin/php-fpm -t /usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php .ini -y /usr/local/php/etc/php-fpm .conf -t #启动php-fpm /usr/local/php/sbin/php-fpm /usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php .ini -y /usr/local/php/etc/php-fpm .conf #关闭php-fpm kill -INT ` cat /usr/local/php/var/run/php-fpm .pid` #重新启动php-fpm kill -USR2 ` cat /usr/local/php/var/run/php-fpm .pid` |
二,php-fpm.conf重要參数具体解释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | pid = run /php-fpm .pid #pid设置,默认在安装文件夹中的var/run/php-fpm.pid。建议开启 error_log = log /php-fpm .log #错误日志,默认在安装文件夹中的var/log/php-fpm.log log_level = notice #错误级别. 可用级别为: alert(必须马上处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice. emergency_restart_threshold = 60 emergency_restart_interval = 60s #表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数假设超过 emergency_restart_threshold个,php-fpm就会优雅重新启动。这两个选项一般保持默认值。 process_control_timeout = 0 #设置子进程接受主进程复用信号的超时时间. 可用单位: s(秒), m(分), h(小时), 或者 d(天) 默认单位: s(秒). 默认值: 0. daemonize = yes #后台执行fpm,默认值为yes,假设为了调试能够改为no。在FPM中,能够使用不同的设置来执行多个进程池。 这些设置能够针对每一个进程池单独设置。 listen = 127.0.0.1:9000 #fpm监听端口。即nginx中php处理的地址。一般默认值就可以。可用格式为: 'ip:port', 'port', '/path/to/unix/socket'. 每一个进程池都须要设置. listen.backlog = -1 #backlog数,-1表示无限制。由操作系统决定,此行凝视掉就可以。
listen.allowed_clients = 127.0.0.1 #同意訪问FastCGI进程的IP,设置any为不限制IP,假设要设置其它主机的nginx也能訪问这台FPM进程。listen处要设置成本地可被訪问的IP。
listen.owner = www listen.group = www listen.mode = 0666 #unix socket设置选项,假设使用tcp方式訪问。这里凝视就可以。 user = www group = www #启动进程的帐户和组 pm = dynamic #对于专用服务器,pm能够设置为static。 #怎样控制子进程,选项有static和dynamic。假设选择static。则由pm.max_children指定固定的子进程数。假设选择dynamic,则由下开參数决定: pm.max_children #。子进程最大数 pm.start_servers #,启动时的进程数 pm.min_spare_servers #,保证空暇进程数最小值,假设空暇进程小于此值,则创建新的子进程 pm.max_spare_servers #,保证空暇进程数最大值,假设空暇进程大于此值,此进行清理 pm.max_requests = 1000 #设置每一个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常实用的. 假设设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0. pm.status_path = /status #FPM状态页面的网址. 假设没有设置, 则无法訪问状态页面. 默认值: none. munin监控会使用到 ping .path = /ping #FPM监控页面的ping网址. 假设没有设置, 则无法訪问ping页面. 该页面用于外部检測FPM是否存活而且能够响应请求. 请注意必须以斜线开头 (/)。 ping .response = pong #用于定义ping请求的返回相应. 返回为 HTTP 200 的 text/plain 格式文本. 默认值: pong. request_terminate_timeout = 0 #设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止执行的脚本实用. 设置为 '0' 表示 'Off'.当常常出现502错误时能够尝试更改此选项。 request_slowlog_timeout = 10s #当一个请求该设置的超时时间后,就会将相应的PHP调用堆栈信息完整写入到慢日志中. 设置为 '0' 表示 'Off' slowlog = log/$pool.log.slow #慢请求的记录日志,配合request_slowlog_timeout使用 rlimit_files = 1024 #设置文件打开描写叙述符的rlimit限制. 默认值: 系统定义值默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048改动。 rlimit_core = 0 #设置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整数. 默认值: 系统定义值. chroot = #启动时的Chroot文件夹. 所定义的文件夹须要是绝对路径. 假设没有设置, 则chroot不被使用. chdir = #设置启动文件夹。启动时会自己主动Chdir到该文件夹. 所定义的文件夹须要是绝对路径. 默认值: 当前文件夹。或者/文件夹(chroot时) catch_workers_output = yes #重定向执行过程中的stdout和stderr到基本的错误日志文件里. 假设没有设置, stdout 和 stderr 将会依据FastCGI的规则被重定向到 /dev/null . 默认值: 空. |
三,常见错误及解决的方法整理
1,request_terminate_timeout引起的资源问题
request_terminate_timeout的值假设设置为0或者过长的时间,可能会引起file_get_contents的资源问题。
假设file_get_contents请求的远程资源假设反应过慢,file_get_contents就会一直卡在那里不会超时。我们知道php.ini 里面max_execution_time 能够设置 PHP 脚本的最大执行时间,可是。在 php-cgi(php-fpm) 中,该參数不会起效。真正能够控制 PHP 脚本最大执行时间的是 php-fpm.conf 配置文件里的request_terminate_timeout參数。
request_terminate_timeout默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当全部的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。改动该參数,设置一个 PHP 脚本最大执行时间是必要的,可是,治标不治本。比如改成 30s,假设发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟仅仅能处理 5 个请求。WebServer 相同非常难避免”502 Bad Gateway”。解决的方法是request_terminate_timeout设置为10s或者一个合理的值,或者给file_get_contents加一个超时參数。
1 2 3 4 5 6 7 | $ctx = stream_context_create( array ( 'http' => array ( 'timeout' => 10 //设置一个超时时间,单位为秒 ) )); file_get_contents ( $str , 0, $ctx ); |
2,max_requests參数配置不当,可能会引起间歇性502错误:
1 | pm.max_requests = 1000 |
设置每一个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常实用的. 假设设置为 ’0′ 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.
这段配置的意思是。当一个 PHP-CGI 进程处理的请求数累积到 500 个后,自己主动重新启动该进程。
可是为什么要重新启动进程呢?
一般在项目中,我们多多少少都会用到一些 PHP 的第三方库,这些第三方库常常存在内存泄漏问题,假设不定期重新启动 PHP-CGI 进程。势必造成内存使用量不断增长。因此 PHP-FPM 作为 PHP-CGI 的管理器。提供了这么一项监控功能。对请求达到指定次数的 PHP-CGI 进程进行重新启动。保证内存使用量不增长。
正是因为这个机制,在高并发的站点中,常常导致 502 错误,我推測原因是 PHP-FPM 对从 NGINX 过来的请求队列没处理好。只是我眼下用的还是 PHP 5.3.2。不知道在 PHP 5.3.3 中是否还存在这个问题。
眼下我们的解决方法是。把这个值尽量设置大些。尽可能降低 PHP-CGI 又一次 SPAWN 的次数。同一时候也能提高整体性能。在我们自己实际的生产环境中发现,内存泄漏并不明显。因此我们将这个值设置得非常大(204800)。大家要依据自己的实际情况设置这个值,不能盲目地加大。
话说回来,这套机制目的仅仅为保证 PHP-CGI 只是分地占用内存。为何不通过检測内存的方式来处理呢?我非常认同高春辉所说的,通过设置进程的峰值内在占用量来重新启动 PHP-CGI 进程,会是更好的一个解决方式。
3,php-fpm的慢日志。debug及异常排查神器:
request_slowlog_timeout设置一个超时的參数。slowlog设置慢日志的存放位置
1 | tail -f /var/log/www .slow.log |
上面的命令就可以看到执行过慢的php过程。
大家能够看到常常出现的网络读取超过、Mysql查询过慢的问题,依据提示信息再排查问题就有非常明白的方向了。
php-fpm 5.3+ 怎样关闭 重新启动?
php 5.3+ 下的php-fpm 不再支持 php-fpm 曾经具有的 /usr/local/php/sbin/php-fpm (start|stop|reload)等命令,须要使用信号控制:
master进程能够理解以下信号
INT, TERM 立马终止 QUIT 平滑终止 USR1 又一次打开日志文件 USR2 平滑重载全部worker进程并又一次加载配置和二进制模块
演示样例:
php-fpm 关闭:
kill -INT `cat /usr/local/php/var/run/php-fpm.pid`
php-fpm 重新启动:
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`
查看php-fpm进程数:
ps aux | grep -c php-fpm
8.命令行下执行php,提示找不到命令
-bash: /usr/bin/php: No such file or directory
vi /etc/profile
在文件底部添加一行配置
export PATH=/usr/local/php/bin:$PATH
保存退出
source /etc/profile
来源:http://www.cnblogs.com/argb/p/3604340.html
php-fpm參数优化
php-fpm进程设置多少合适,设成动态还是静态?
《lnmp一键安装包》中会依据你服务器内存调整php-fpm进程数。
以下是摘自Google讨论话题:《 PHP-FPM on highload tips 》[墙外。FQ可參考goagent]。
When you running a highload website with PHP-FPM via FastCGI, the following tips may be useful to you
假设你的高负载站点使用PHP-FPM管理FastCGI。或许以下这些技巧对你实用
1. Compile PHP's modules as less as possible, the simple the best (fast);
尽量少安装PHP模块。最简单是最好(快)的
2. Increas PHP FastCGI child number to 100 and even more. Sometime, 200 is OK! ( On 4GB memory server);
把你的PHP FastCGI子进程数调到100或以上,在4G内存的服务器上200就能够(建议压力測试来得出自己服务器合理的值)
3. Using SOCKET PHP FastCGI, and put into /dev/shm on Linux;
socket连接FastCGI。/dev/shm是内存文件系统,socket放在内存中肯定会快些
4. Increase Linux "max open files", using the following command (must be root):
Linux下添加文件打开数,命令例如以下:
5. Increase PHP-FPM open file description rlimit:
添加 PHP-FPM 打开文件描写叙述符的限制:
6. Using PHP code accelerator, e.g eAccelerator, XCache. And set "cache_dir" to /dev/shm on Linux.
使用php代码加速器,比如 eAccelerator, XCache.在Linux平台上能够把`cache_dir`指向 /dev/shm
/usr/local/php/etc/php-fpm.conf重要优化參数具体解释:
pm參数指定了进程管理方式,有两种可供选择:static或dynamic。从字面意思不难理解。为静态或动态方式。假设是静态方式。那么在php-fpm启动的时候就创建了指定数目的进程,在执行过程中不会再有变化(并非真的就永远不变)。而动态的则在执行过程中动态调整。当然并非无限制的创建新进程,受pm.max_spare_servers參数影响;动态适合小内存机器,灵活分配进程,省内存。静态适用于大内存机器。动态创建回收进程对服务器资源也是一种消耗
static模式下创建的子进程数或dynamic模式下同一时刻同意最大的php-fpm子进程数量
#动态方式下的起始php-fpm进程数量
#动态方式下服务器空暇时最小php-fpm进程数量
#动态方式下服务器空暇时最大php-fpm进程数量
一般php-fpm进程占用20~30m左右的内存就按30m算。
假设单独跑php-fpm,动态方式起始值可设置物理内存Mem/30M,因为大家一般Nginx、MySQL都在一台机器上。于是预留一半给它们,即php-fpm进程数为$Mem/2/30。
LNMP在一台机器上參数(仅供參考。建议压力測试得出):
987M内存:
来源:https://blog.linuxeye.com/380.html