1.worker_processes 越大越好(一定数量后性能增加不明显)
标签归档:php-fpm
PHP的性能演进(从PHP5.0到PHP7.1的性能速度全评测)
导读:PHP 是 Web 开发最常用的语言,每个大版本的更新都带来不少新特性和性能提升。特别是 PHP 7.0 的发布,带来 PHP
性能飞跃。本文作者对各个 PHP 版本进行了 CPU 性能基准测试,并且带来了PHP下个大版本的消息。本文中文版由高可用架构志愿者翻译。
自 1994 年 Rasmus Lerdorf 创建 PHP 以来, PHP 语言经历了许多改进,其中性能是开发人员在评估新版本时考虑的主要标准之一。
阅读这篇文章,可以了解从 PHP 5 到 7(包括 7.1)的性能提升,同时也将了解到即将加入到 PHP 8 的试验性的 JIT 分支版本的性能。
简介
本文将根据时间作出更新,增加更多信息和基准测试结果,包括尚未发布的新版本,以便更好地了解多年来 PHP 性能演变。如果您有更正或建议改进,请在文后留言。
自 1994 年 Rasmus Lerdorf 创建 PHP 以来, PHP 语言经历了激烈的演进。虽然第一版是一个简单的一人开发的
CGI 程序,Rasmus Lerdorf、Andi Gutmans 和 Zeev Suraski
加入了该语言的第三个版本的开发,并根本性重新设计。从那之后, PHP 开发组也创建并发展起来。
随着项目的发展,由于 PHP 3 天然的可扩展性, PHP 在核心和附加扩展开发的功能得到了蓬勃发展,如网络通信,解析,缓存和数据库支持。
语言本身也在发展,带来了一系列的改进。这包括支持面向对象的结构,例如类,接口, traits,闭包等。
对于许多开发人员来说,仅有新功能是不够的。随着语言越来越受欢迎, PHP 社区对于提供更好性能,可扩展性和更少内存使用的需求越来越强烈。
PHP 开发团队近 20 年来一直致力于解决这些需求,虽然 PHP 3 的引入大大提高了性能,但直到 Andi Gutmans 和 Zeev Suraski 引入 Zend Engine 并发布 PHP 4, PHP 的性能才开始变得正式起来。
2000 年推出的新的内存编译器和执行器模型大大提高了 PHP 的性能(提高了 5 倍甚至 10 倍),并首次被正式的 Web 应用程序和站点所使用。我们可以说,今天 PHP 的成果远远超出了任何人在 PHP 项目诞生时的期望。
PHP 的蓬勃发展增加了改善性能的欲望。幸运的是, Zend Engine 中设计的模型为持续优化性能提供了良好的基础。
虽然 PHP 5.0 没有带来实质性的性能提升,并且在某些情况下甚至比 PHP4 更慢,一个由 Dmitry Stogov
领导的团队在社区的大力帮助下已经在后续版本中不断优化语言,在 PHP 5.6 发布的时候,在大多数情况下,性能提升在 1.5x 和 3x 之间。
2015 年 12 月, PHP 7.0 取得了重大突破。 2016 年 12 月,7.1 版本也带来了一系列增强功能。
PHP 8 性能展望
这是一个前途光明的版本,目前正在开发当中,由 Zend 的 Dmitry Stogov 主导。虽然它是基于 PHP 7.1 版本基础,但实际版本号尚未定义,所以本文称这个版本为“试验 JIT”分支下。
关键功能 JIT(Just-In-Time)编译,是一种将代码转换为另一种字节码(比如运行它的机器 CPU 的本地代码)的技术。 JIT 可以使程序运行更快。
本文涵盖了几个基准测试的结果,从 PHP 5 的第一个版本到 PHP 的试验性 JIT 分支版本,PHP 5 之前的版本性能本文不作介绍。
在写这篇文章的时候,我们很难确定 PHP 8 之前是否会有另一个主要版本,比如 PHP 7.2。但是可以假设在 PHP 8 发布时,它已经包括当前试验版 JIT 分支的强大功能。
PHP 性能评估
本文只运行纯 CPU 任务脚本的基准测试(不需要I / O操作的任务例如访问文件,网络或数据库连接)。
使用的基准测试脚本如下所示:
- bench.php 可在PHP源代码的 php-src/Zend 目录
- micro_bench.php 也可以在 PHP 源代码发布的 php-src/Zend 目录中找到
- mandelbrot.php https://gist.githubusercontent.com/dstogov/12323ad13d3240aee8f1/raw/37fed3beb7e666b70e199bcf361af541b3c30d2d/b.php
基准脚本仅使用每个PHP主要版本的最新小版本运行。因此,测试的版本如下:
- 5.0.5
- 5.1.6
- 5.2.17
- 5.3.29
- 5.4.45
- 5.5.38
- 5.6.28
- 7.0.13
- 7.1.0
- PHP-JIT(JIT实验分支)
当然,我想确定,我们在相同的基准上运行所有小版本,例如在 5.3.0 到 5.3.29 之间。结果是有说服力的:性能方面的主要增强不是由小版本带来的,而是主要版本号的变化,例如从 PHP 5.4 到 PHP 5.5,或从PHP 5.6 到 PHP 7。
小版本没有显示任何明显的性能改进。这意味着相同的脚本应该以相同的速度运行,无论您使用 PHP 5.4.0 还是 PHP 5.4.45。
您可以查看基准进程部分,详细说明主机系统的设置,各个基准的运行方式以及如何解释时序结果。
纯 CPU 基准测试结果
这部分给出了每个 PHP 版本的基准测试结果。
每个基准列显示 3 个值:
- 时间: 执行时间,以秒和毫秒为单位
- %rel, gain:相对于以前的版本收益的执行时间。 在下面的表格中,例如,%rel。 bench.php 和版本 5.3.29 的收益是 31.89%,意味着该脚本比 5.2.17 版本运行快 31.89%。
- %abs, gain:与 PHP 5.0 相比脚本运行的收益。 如果你看看bench.php 和试验性的 JIT 分支的这个列的交集,你会注意到,对于这个特定的测试基准,PHP 8 比 PHP 5.0 快 41 倍以上。
纯CPU基准测试的结果如下所示:
(1)测试不能在 5.3 之前的版本上运行,因为它使用了尚未实现的对象功能。
(2)此列中的结果有点偏颇,因为基准需要至少 PHP 5.3 运行。把它们当成纯粹说明,因为他们不能与 PHP 5.0 性能进行比较。
(3)这是一个 mandelbrot.php 脚本的修改版本,它运行得太快,在 7.1.0 和试验 JIT 分支无法准确的统计时间,我们在脚本中运行计算 100 次而不是 1 次。
当然,这些都是纯 CPU 的基准测试。它们不涵盖 PHP 性能的所有方面,它们可能不代表真实情况。但是结果足够显著,足以说明几个方面的问题:
- PHP 5.1 将 PHP 5.0的 性能提高了一倍多
- 5.2 和 5.3 带来了他们自己的一些性能增强,但他们没有像5.1版本那样引人注目。
- 5.4 版本是一个大的性能改进。(这里有我曾经分享过的PHP5.4的性能优化的演讲PPTPHP-5.4 Performance)
- opcache 扩展插件与 5.5 和 5.6 版捆绑在一起。当相同的脚本在 Web 服务器连续运行时,由于更快的代码加载会带来性能增强。但是,opcache 不会真正显示其在CLI模式下执行脚本的优势。
- PHP 7.0 是性能方面的一个重大突破。 Zend Engine 已经完全重新设计,我们可以在这里看到这项工作的结果。(这里有我曾经分享过的PHP7的性能优化的演讲的PPT The secret of PHP7′s Performance )
-
PHP 7.1 在 opcache 扩展中引入了 opcode 优化。这再次解释了上述表格中当与 7.0 相比时,性能的增益。(这里有我曾经分享过的PHP7.1的性能优化的演讲PPT
- --prefix=/usr/local/php
- --disable-debug
- --disable-phpdbg
- --enable-mysqlnd
- --enable-bcmath
- --with-bz2=/usr
- --enable-calendar
- --with-curl
- --enable-exif
- --enable-fpm
- --with-freetype-dir
- --enable-ftp
- --with-gd
- --enable-gd-jis-conv
- --enable-gd-native-ttf
- --with-gettext=/usr
- --with-gmp
- --with-iconv
- --enable-intl
- --with-jpeg-dir
- --enable-mbstring
- --with-mcrypt
- --with-openssl
- --enable-pcntl
- --with-pdo-mysql=mysqlnd
- --with-png-dir
- --with-recode=/usr
- --enable-shmop
- --enable-soap
- --enable-sockets
- --enable-sysvmsg
- --enable-sysvsem
- --enable-sysvshm
- --enable-wddx
- --with-xmlrpc
- --with-xsl
- --with-zlib=/usr
- --enable-zip
- --with-mysqli=mysqlnd
注意,在编译旧版时,上面的一些选项需要被禁用或被其他替代,并且并不是所有的扩展都可用或可以被编译。
运行基准测试
每个基准测试都使用 PHP CLI 专用脚本运行,该脚本遵循以下步骤:
使用 microtime()函数从内部获取脚本执行时间。 在此修改后,基准脚本将如下所示:
- <?php
- $__start__ = microtime( true );
- /***
- original benchmark script code here
- ***/
- fprintf( STDERR, microtime( true ) - $__start__);
- ?>
执行 2 次运行,以确保 PHP 可执行文件和基准测试脚本内容都在操作系统缓存中
运行脚本 5 次,并提取最小,最大和平均运行时间,如脚本报告。 本文仅显示平均运行时间,称之为“脚本运行时间”。php.ini 文件如下所示:
- engine = On
- short_open_tag = Off
- realpath_cache_size = 2M
- max_execution_time = 86400
- memory_limit = 1024M
- error_reporting = 0
- display_errors = 0
- display_startup_errors = 0
- log_errors = 0
- default_charset = "UTF-8"
- [opcache]
- zend_extension=opcache.so
- opcache.enable=1
- opcache.enable_cli=1
- opcache.optimization_level=-1
- opcache.fast_shutdown=1
- opcache.validate_timestamps=1
- opcache.revalidate_freq=60
- opcache.use_cwd=1
- opcache.max_accelerated_files=100000
- opcache.max_wasted_percentage=5
- opcache.memory_consumption=128
- opcache.consistency_checks=0
- opcache.huge_code_pages=1
- // PHP 8/Next only
- opcache.jit=35
- opcache.jit_buffer_size=32M
分析运行结果
使用 Unix time 命令来计时,输出如下所示:
- $ time php bench.php
- real: 0m1.96s
- user: 0m1.912s
- sys: 0m0.044s
第一个值,real : 是命令开始到终止之间的时间(当你回到 shell 提示符)。
第二个值,user :说明在用户模式中花费的时间(在我们的例子中,这是在 php 可执行文件中花费的时间)。
最后一个值 sys :说明在操作系统(内核)调用中花费的时间。这个值应该是最小的,但是如果你的代码访问缓慢的设备结果会比较大。重负载的操作系统也可能影响此处报告的值。
在空闲系统上通常,数量(user + sys)应该非常接近 real。这是在上面的例子中的情况:user + sys =
1.956s,real 是 1.960s。 0.004s 的差异不属于当前进程:它仅仅意味着操作系统执行任务所花费的额外时间,例如调度。同一个脚本在一个负载很重的系统上执行,并行编译 3 个不同的 PHP 版本:
- $ time php bench.php
- real: 0m7.812s
- user: 0m2.02s
- sys: 0m0.101s
在这里我清楚地看到,系统本身的重负载对使用的时间(也许在系统时间)有重大影响。
这就是为什么我在这个基准中保留一个额外的值,操作系统开销,这是调用的时间和(用户+系统)时间之间的差。
在纯 CPU 基准测试活动期间,我确保在 99% 以上的时间,这个值严格小于 100 毫秒,即使运行需要几十秒钟完成的脚本。
特别鸣谢
特别鸣谢 Dmitry Stogov 和所有 PHP 核心开发者们。
本文是和 Dmitry Stogov 合作完成的 , 他帮助审阅了文章内容 , 来保证这个文章的正确性。
Dmitry Stogov 曾经是 Truck MMCache 的开发者,在 PHP4 时代就可以用作共享内存中缓存 PHP Opcode,从那时候起,Dmitry Stogov 就加入了 Zend,一直到现在。
Dmitry 是 PHP NG 的主要开发者 , 也就是我们后来知道的 PHP7, 和 Dmitry 一起合作的有 Xinchen Hui(就是我 ),Nikita Popov,正是他们在一起开发了 PHP7 以及后来的版本包括 PHP JIT。
在 PHP7 之前 , PHP5 时代的 Andi Gumans, Zeev Suraski 以及 Stas Malishev 等也做了很多的工作来提升 PHP5 的性能,限于篇幅,本文就不详细介绍。
结论
本文的目的是给你一个不同版本PHP性能的概述,从 5.0 开始,到当前正在开发的最新版本,使用一组已知的基准脚本。
它还为您提供了由每个连续 PHP 版本解决的性能改进方面的列表。
本文将随着新的 PHP 版本的公布而更新,并且将来会添加新的基准测试结果。 我也希望添加一些真实世界的 PHP 应用程序,如 WordPress 的基准测试结果。
如果您有任何问题或发现不准确,请随时发表评论。 同时,与其他对 PHP 性能感兴趣的开发人员分享这篇文章。
http://www.laruence.com/2016/12/18/3137.html
网站502与504错误分析及解决办法
不管你是做运维还是做开发,哪怕你是游客,时不时会遇到502 Bad Gateway或504 Gateway Time-out。出现这页面,把服务重启下,再实在不行重启下服务器,问题就解决了,但是,这问题还是会困扰着你,特别是做运维的人员。夜黑风高正酣睡时,一个电话响起,让你重启服务或IISRESET,肯定是极大不爽,立马要问候他妈了。呵呵,本文总结502与504故障分析与解决方法。
二. 状态码解释
502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
504 Gateway Time-out:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。
三. 502 Bad Gateway原因分析
将请求提交给网关如php-fpm执行,但是由于某些原因没有执行完毕导致php-fpm进程终止执行。说到此,这个问题就很明了了,与网关服务如php-fpm的配置有关了。
php-fpm.conf配置文件中有两个参数就需要你考虑到,分别是max_children和request_terminate_timeout。
max_children最大子进程数,在高并发请求下,达到php-fpm最大响应数,后续的请求就会出现502错误的。可以通过netstat命令来查看当前连接数。
request_terminate_timeout设置单个请求的超时终止时间。还应该注意到php.ini中的max_execution_time参数。当请求终止时,也会出现502错误的。
当积累了大量的php请求,你重启php-fpm释放资源,但一两分钟不到,502又再次呈现,这是什么原因导致的呢? 这时还应该考虑到数据库,查看下数据库进程是否有大量的locked进程,数据库死锁导致超时,前端终止了继续请求,但是SQL语句还在等待释放锁,这时就要重启数据库服务了或kill掉死锁SQL进程了。
对于长时间的请求可以考虑使用异步方式,可以参阅《关于PHP实现异步操作的研究》。
四. 504 Gateway Time-out原因分析
504错误一般是与nginx.conf配置有关了。主要与以下几个参数有关:fastcgi_connect_timeout、fastcgi_send_timeout、fastcgi_read_timeout、fastcgi_buffer_size、fastcgi_buffers、fastcgi_busy_buffers_size、fastcgi_temp_file_write_size、fastcgi_intercept_errors。特别是前三个超时时间。如果fastcgi缓冲区太小会导致fastcgi进程被挂起从而演变为504错误。
五. 小结
总而言之,502错误主要从四个方向入手:
1. max_children
2. request_terminate_timeout、max_execution_time
3. 数据库
4. 网关服务是否启动如php-fpm
504错误主要查看nginx.conf关于网关如fastcgi的配置。
php增加 ffmpeg-php 安装及出错解决办法
安装ffmpeg-php插件
wget http://www.tortall.net/projects/yasm/releases/yasm-0.7.0.tar.gz
tar xzvf yasm-0.7.0.tar.gz
cd yasm-0.7.0
./configure
make
make install
svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
cd ffmpeg
./configure –enbale-shared
make
make install
wget http://nchc.dl.sourceforge.net/project/ffmpeg-php/ffmpeg-php/0.6.0/ffmpeg-php-0.6.0.tbz2
tar xvjf ffmpeg-php-0.6.0.tbz2
cd ffmpeg-php-0.6.0
/usr/local/php/bin/phpize
./configure –with-php-config=/usr/local/php/bin/php-config
make
报错:
make: *** [ffmpeg_movie.lo] Error 1
解决:
vim ffmpeg_movie.c
row 311: list_entry *le; 改为zend_rsrc_list_entry *le;
row 346: list_entry new_le;改为 zend_rsrc_list_entry new_le;
row 360: hashkey_length+1, (void *)&new_le, sizeof(list_entry),改为hashkey_length+1, (void *)&new_le,sizeof(zend_rsrc_list_entry),
重新编译,
make test
报错:
The test-suite requires that proc_open() is available.
解决:
编辑php.ini文件,找到disable_functions去掉proc_open。
make install
vim /usr/local/php/etc/php.ini
/etc/init.d/php-fpm restar
运行ffmpeg报错如下:
ffmpeg: error while loading shared libraries: libavdevice.so.52: cannot open shared object file: No such file or directory
解决:
vim /etc/ld.so.conf
加入一行:/usr/local/lib
然后执行 ldconfig
make ffmpeg-php时,出现error ‘PIX_FMT_RGBA32‘ undeclared…
解决方法:
vi ffmpeg_frame.c, 替换PIX_FMT_RGBA32为/PIX_FMT_RGB32
执行/usr/local/php/sbin/php-fpm restart时报错:
/usr/local/php/bin/php-cgi: symbol lookup error: /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/ffmpeg.so: undefined symbol: register_ffmpeg_frame_class
解决方法同上,然后重编译安装ffmpeg-php
While compiling ffmpeg-php from source with make command you may get the following error terminating your making process;
make: *** [ffmpeg_frame.lo] Error 1
This error occurs due to a missing file ‘ffmpeg_frame.lo‘ in the ffmpeg-php source, while your ffmpeg-php source may contain the file named ‘ffmpeg_frame.loT‘.
To Resolve this issue you just need to rename the ‘ffmpeg_frame.loT‘ to ‘ffmpeg_frame.lo‘ and make again, Please check below steps :
Go to ffmpeg-php source directory :
Note: your ffmpeg-php version may be different, i am using 0.6.0
[root@hostripples ~]# cd /path/to/ffmpeg-php-0.6.0
Now rename or copy the ‘ffmpeg_frame.loT‘ to ‘ffmpeg_frame.lo‘
[root@hostripples ~]# mv ffmpeg_frame.loT ffmpeg_frame.lo
Once you have successfully renamed/copied the file to ‘ffmpeg_frame.lo’, you should compile it again with make command.
– See more at: http://blog.hostripples.com/ffmpeg-php-make-ffmpeg_frame-lo-error-1/#sthash.q6KOWHag.dpuf
If you get the following error when running the command make to compile FFmpeg:
make: *** [ffmpeg_frame.lo] Error 1
There are two ways to fix this problem:
*** First solution (highly recommended)
In the latest version of ffmpeg-php (0.6.0), you need to modify the file: ffmpeg_frame.c and replace every instance of PIX_FMT_RGBA32 with PIX_FMT_RGB32
Using Linux text editor, vi run the following commands:
vi ffmpeg_frame.c
:%s/PIX_FMT_RGBA32/PIX_FMT_RGB32
:wq!
Here, you should be back to the command line. Run these commands to compile and install FFmpeg-Php:
./configure
make
make install
*** Second solution
Run the following commands:
cd /path/to/ffmpeg-php-0.6.0
cp -aP ffmpeg_frame.loT ffmpeg_frame.lo
make clean
./configure
Then recompile and install ffmpeg.
php日志错误分析:网站http返回502与504错误分析
一. 戏说
不管你是做运维还是做开发,哪怕你是游客,时不时会遇到502 Bad Gateway或504 Gateway Time-out。出现这页面,把服务重启下,再实在不行重启下服务器,问题就解决了,但是,这问题还是会困扰着你,特别是做运维的人员。夜黑风高正酣睡 时,一个电话响起,让你重启服务或IISRESET,肯定是极大不爽,立马要问候他妈了。呵呵,本文总结502与504故障分析与解决方法。
二. 状态码解释
502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
504 Gateway Time-out:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。
三. 502 Bad Gateway原因分析
将请求提交给网关如php-fpm执行,但是由于某些原因没有执行完毕导致php-fpm进程终止执行。说到此,这个问题就很明了了,与网关服务如php-fpm的配置有关了。
php-fpm.conf配置文件中有两个参数就需要你考虑到,分别是max_children和request_terminate_timeout。
max_children最大子进程数,在高并发请求下,达到php-fpm最大响应数,后续的请求就会出现502错误的。可以通过netstat命令来查看当前连接数。
request_terminate_timeout设置单个请求的超时终止时间。还应该注意到php.ini中的max_execution_time参数。当请求终止时,也会出现502错误的。
当积累了大量的php请求,你重启php-fpm释放资源,但一两分钟不到,502又再次呈现,这是什么原因导致的呢? 这时还应该考虑到数据库,查看下数据库进程是否有大量的locked进程,数据库死锁导致超时,前端终止了继续请求,但是SQL语句还在等待释放锁,这时 就要重启数据库服务了或kill掉死锁SQL进程了。
对于长时间的请求可以考虑使用异步方式,可以参阅《关于PHP实现异步操作的研究》。
四. 504 Gateway Time-out原因分析
504错误一般是与nginx.conf 配置有关了。主要与以下几个参数有关:fastcgi_connect_timeout、fastcgi_send_timeout、 fastcgi_read_timeout、fastcgi_buffer_size、fastcgi_buffers、 fastcgi_busy_buffers_size、fastcgi_temp_file_write_size、 fastcgi_intercept_errors。特别是前三个超时时间。如果fastcgi缓冲区太小会导致fastcgi进程被挂起从而演变为 504错误。
五. 小结
总而言之,502错误主要从四个方向入手:
1. max_children
2. request_terminate_timeout、max_execution_time
3. 数据库
4. 网关服务是否启动如php-fpm
504错误主要查看nginx.conf关于网关如fastcgi的配置
php日志分析:解决NGINX+PHP-FPM failed to ptrace(PEEKDATA) Input/output error出错问题
今天查看php的错误日志 (error_log = /usr/local/php/var/log/php-fpm.log ) 和 慢日志(slowlog = /usr/local/php/var/log/php-fpm.log.slow ) , 发现错误日志里很多 “ ERROR: failed to ptrace(PEEKDATA) pid 4276: Input/output error (5) ”这样的错误 , 想找出出现这错误的原因于是从网上搜了如下的 文章 。他说是他的网站经常出现 ”bad gateway“ 错误才去查日志 发现有这个错误 。 我现在还不知道 我的 日志里出现这样的错误 是不是 我的页面也出现 ”bad gateway“ 的错误 。 带查证ing。
查了 好几个资料都说是 php开启了慢日志 引起的 为了让系统不出现异常 决定吧慢日志 注释掉。
资料 一:
网站总是出现bad gateway 提示,时有,时无,查看了一下error_log日志,居然出现一堆错误,如下
网上也找了很多方法,很多人说是 rlimit_files
打开文件数的问题,但是觉得不太靠谱,最后找到鬼佬的话,看上去还有几分道理。
http://serverfault.com/questions/406532/i-o-error-with-php5-fpm-ptracepeekdata-failed
It appears you have request_slowlog_timeout enabled. This normally takes any request longer than N seconds, logs that it was taking a long time, then logs a stack trace of the script so you can see what it was doing that was taking so long.
In your case, the stack trace (to determine what the script is doing) is failing. If you’re running out of processes, it is because either:
After php-fpm stops the process to trace it, the process fails to resume because of the error tracing it
The process is resuming but continues to run forever.
My first guess would be to disable request_slowlog_timeout. Since it’s not working right, it may be doing more harm than good. If this doesn’t fix the issue of running out of processes, then set the php.ini max_execution_time to something that will kill the script for sure.
看样子是因为我打开了slowlog 然后,再设置 了 request_slowlog_timeout
这个参数,,所以后php 没有执行完就出错了。。
上面解决的办法是:
禁用 php-fpm.conf 里的 request_slowlog_timeout
和 slowlog
,然后,修改 php.ini 里的max_execution_time
参数
资料 二 :
最近服务器频繁出现502(nginx+php+php-fpm的架构),调试过程中在php-fpm的日志中发现了大量的:
经对比最近两次系统调优所使用的配置文件发现,是因为php-fpm的配置引起:
解决办法是注释掉上面的配置即可。/etc/init.d/php-fpm restart生效
Nginx + FastCgi + Spawn-fcgi + c 的架构搭建
Php写的很有段时间了,最近看公司一些关键的后端CGI都是用C写的,以lighthttp 最为server 。忽然也有种学习用C写CGI的想法。虽然php结合php-fpm的fastcgi模式也有不错的性能,反正多学一种东西又有和不可以呢?何况,某些情况下C的性能还是php无法比拟的。
先有必要有这样第一个认识:ngxin作为一个webserver,本身并不包含CGI的解释器,需要通过一个中间件【例如php-fpm】来运行CGI。他们之间的模式大致是:
nginx <– socket –> php-fpm——–>php
那么nginx既然要运行c写的CGI那么也应该有类似php-fpm的东西。baidu, google了下,发现有一个spawn-fcgi的东西。原本是lighttp 内的fastcgi进程管理器。 于是又搜索了下,折腾了一个下午,终于抛出了经典的hello world !!! 。下面是具体步骤:
大致分为5步:
1、安装Spawn-fcgi 【启动cgi的时候需要】
wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.gz tar zxvf lighttpd-1.4.19.tar.gz cd lighttpd-1.4.19 ./configure make
复制 编译好的spawn-fcgi到 nginx目录,很主要!!!!
cp ./src/spawn-fcgi /usr/local/nginx/sbin/
2、安装fastcgi库:: 【提供编写cgi时的类库】
wget http://www.fastcgi.com/dist/fcgi.tar.gz tar zxvf fcgi.tar.gz cd fcgi ./configure make make install
fcgio.cpp:50: error: ‘EOF’ was not declared in this scope解决办法PS:
我想这个fcgi开发一点也不活跃,而gcc的最新版本不断出来,很有可能是由于这方面引的原因,我又调整了一下关键字
gcc compile fcgi,(之前都是没有方向的搜索)。终于在第一条结果中找到原因了:http://bugs.gentoo.org/256654
解决办法:
在/include/fcgio.h文件中加上 #include <cstdio>,然后再编译安装就通过了。
3、测试代码::
#include <fcgi_stdio.h> int main( int argc, char *argv[] ) { while( FCGI_Accept() >= 0 ) { FCGI_printf( "Status: 200 OK\r\n" ); FCGI_printf( "Content-Type: text/html\r\n\r\n" ); FCGI_printf( "Hello world in C\n" ); } return 0; }
编译::
g++ -o test.cgi test.cpp -L /usr/local/lib/ -lfcgi
4、启动Spawn-fcgi::
spawn-fcgi -a 127.0.0.1 -p 7000 -u www -f /data/cgi-bin/test.cgi
如果报: error while loading shared libraries: libfcgi.so.0: cannot open shared object file: No such file or directory
请执行如下命令:为了这个错误,折腾了很长时间哦!
cp /usr/local/lib/libfcgi.so.0 /usr/lib
5、配置nginx.conf
location ~ \.cgi$ { fastcgi_pass 127.0.0.1:7000; fastcgi_index index.cgi; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; }
重启nginx
/etc/init.d/nginx reload
PHP-CGI与php-fpm的区别
php-cgi是被调用的进程,php-fpm是配置和管理进程的。
cgi效率低,每次来了PHP请求,新建立一个PHP进程来解析,解析完毕进程销毁,再来请求再起进程。。。
fpm=fastcgi process manage,维持一定数量的进程数,供nginx调用,不用每次都新建进程,速度更快。原理上有点类似于数据库连接池吧。
CGI 是用来接收HTTP请求的一个程序,例如[127.0.0.1/index.php?c=article&id=11,这个请求通过apahce、nginx等等过来,然后http服务器发送给php-cgi(就是php用来接收http的程序),这个玩意儿每次新建一个进程的时候都要读取和加载php.ini的一堆参数,然后才能开始接收请求,比较慢。
FASTCGI的工作原理是首先启动一个master,这个master加载了所有的配置信息等等,master会新建很多个worker,然后每次有请求的时候master负责把请求分配给相应的worker,这样避免了重复加载和启动,就是一个提交cgi程序效能的东西,fastcgi这个东西只是一个协议(你可以理解为是一个没实现的想法),并不是一个程序。
PHP-FPM就是实现这个想法的程序,CGI很蠢,不会管理进程,而PHP-FPM会根据实际情况,创建worker或者关掉worker进程,保持一定量的worker,请求多了,worker就多了,请求少了,worker就会被关掉一部分,你可以理解为它是一个高效CGI的进程管理器。
PHP fastcgi TCP(127.0.0.1:9000)和unix domain socket方式性能对比
Nginx连接fastcgi的方式有2种:TCP和unix domain socket
什么是Unix domain socket?
Unix domain socket 或者 IPC socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信。与管道相比,Unix domain sockets 既可以使用字节流,又可以使用数据队列,而管道通信则只能使用字节流。Unix domain sockets的接口和Internet socket很像,但它不使用网络底层协议来通信。Unix domain socket 的功能是POSIX操作系统里的一种组件。
Unix domain sockets 使用系统文件的地址来作为自己的身份。它可以被系统进程引用。所以两个进程可以同时打开一个Unix domain sockets来进行通信。不过这种通信方式是发生在系统内核里而不会在网络里传播。
下面php fastcgi使用TCP和unix domain socket方式对比
TCP是使用TCP端口连接127.0.0.1:9000
Socket是使用unix domain socket连接套接字/dev/shm/php-cgi.sock(很多教程使用路径/tmp,而路径/dev/shm是个tmpfs,速度比磁盘快得多)
测试机是个1核的centos6.4,2用户并发时系统资源消耗50%左右,10用户资源就跑得很满了。
2users | 10users | ||
nginx/1.2.9 + PHP 5.2.5 | tcp | 1060 | 1294 |
nginx/1.2.9 + PHP 5.2.5 | socket | 997 | 1487 |
nginx/1.2.9 + PHP 5.3.10 | tcp | 906 | 1082 |
nginx/1.2.9 + PHP 5.3.10 | socket | 880 | 1247 |
结论是在服务器压力不大的情况下,tcp和socket差别不大,但在压力比较满的时候,用套接字方式,效果确实比较好。
因为:对于进程间通讯的两个程序,unix domain socket的流程不会走到TCP 那层,直接以文件形式,以stream socket通讯。如果是TCP socket,则需要走到IP层。对于非同一台服务器上,TCP socket走的就更多了。
下面是php 5.3以上版本将TCP改成socket方式的配置方法:
修改php-fpm.conf(/usr/local/php/etc/php-fpm.conf)
;listen = 127.0.0.1:9000 listen = /dev/shm/php-cgi.sock
修改nginx配置文件server段的配置,将http的方式改为socket方式
location ~ .*\.(php|php5)?$ { #fastcgi_pass 127.0.0.1:9000; fastcgi_pass unix:/dev/shm/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; }
重启php-fpm与nginx
service nginx restart service php-fpm restart
ls -al /dev/shm
可以看到php-cgi.sock文件unix套接字类型