PHP运行模式的深入理解
2023-06-13 09:15:00 时间
2)fast-cgi常驻(long-live)型的CGI
3)cli 命令行运行 (CommandLineInterface)
4)web模块模式(apache等web服务器运行的模块模式)
每有一个用户请求,都会先要创建cgi的子进程,然后处理请求,处理完后结束这个子进程,这就是fork-and-execute模式。当用户请求数量非常多时,会大量挤占系统的资源如内存,CPU时间等,造成效能低下。所以用cgi方式的服务器有多少连接请求就会有多少cgi子进程,子进程反复加载是cgi性能低下的主要原因。
如果不想把PHP嵌入到服务器端软件(如Apache)作为一个模块安装的话,可以选择以CGI的模式安装。或者把PHP用于不同的CGI封装以便为代码创建安全的chroot和setuid环境。这样每个客户机请求一个php文件,Web服务器就调用php.exe(win下是php.exe,linux是php)去解释这个文件,然后再把解释的结果以网页的形式返回给客户机。这种安装方式通常会把PHP的可执行文件安装到web服务器的cgi-bin目录。CERT建议书CA-96.11建议不要把任何的解释器放到cgi-bin目录。
这种方式的好处是把webserver和具体的程序处理独立开来,结构清晰,可控性强,同时缺点就是如果在高访问需求的情况下,cgi的进程fork就会成为很大的服务器负担,想象一下数百个并发请求导致服务器fork出数百个进程就明白了。这也是为什么cgi一直背负性能低下,高资源消耗的恶名的原因。
CGI模式安装:
CGI已经是比较老的模式了,这几年都很少用了,所以我们只是为了测试。
安装CGI模式需要注释掉
LoadModulephp5_modulemodules/libphp5.so这行。如果不注释这行会一直走到handler模式。也就是模块模式。
然后在httpd.conf增加action:
Actionapplication/x-httpd-php/cgi-bin/
如果在/cgi-bin/目录找不到php-cgi.可自行从php的bin里面cp一个。
然后重启apache,再打开测试页面发现ServerAPI变成:CGI/FastCGI。说明成功切换为cgi模式。
打开apache错误日志有如下提示:Permissiondenied:execof
可以检查cgi程序的属性,按Linuxcontexts文件里定义的,/usr/local/httpd/cgi-bin/里必须是httpd_sys_script_exec_t属性。 通过ls-Z查看,如果不是则通过如下命令更改:chcon-thttpd_sys_script_exec_t/var/www/cgi-bin/*.cgi如果是虚拟主机里的cgi,则参考问题2使之能正常使用普通的功能后,再通过chcon设置cgi文件的context为
httpd_sys_script_exec_t即可。chcon-R-thttpd_sys_script_exec_tcgi-bin/
2)apache错误提示:....malformedheaderfromscript.Badheader=
根据提示说明有header有问题,查看文件输出的第一句话是什么,应该类似于如下
Content-type:text/plain;charset=iso-8859-1\n\n
或者Content-type:text/html\n\n
注意:声明好Content-type后要输出两个空行。
3)apache错误提示:Execformaterror
脚本解释器设置错误。脚本第一行应该以"#!解释器路径"的形式,填写脚本解释器的路径,如果是PERL程序,常见的路径为:#!/usr/bin/perl或#!/usr/local/bin/perl 如果是PHP程序,不需要填写解释器路径,系统会自动找到PHP。
FastCGI的工作原理是:
(1)、WebServer启动时载入FastCGI进程管理器【PHP的FastCGI进程管理器是PHP-FPM(php-FastCGIProcessManager)】(IISISAPI或ApacheModule);
(2)、FastCGI进程管理器自身初始化,启动多个CGI解释器进程(在任务管理器中可见多个php-cgi.exe)并等待来自WebServer的连接。
(3)、当客户端请求到达WebServer时,FastCGI进程管理器选择并连接到一个CGI解释器。Webserver将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
(4)、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回WebServer。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在WebServer中)的下一个连接。在正常的CGI模式中,php-cgi.exe在此便退出了。
在CGI模式中,你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部dll扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistentdatabaseconnection)可以工作。
2)从安全性上看,Fastcgi支持分布式运算.fastcgi和宿主的server完全独立,fastcgi怎么down也不会把server搞垮.
3)从性能上看,fastcgi把动态逻辑的处理从server中分离出来,大负荷的IO处理还是留给宿主server,这样宿主server可以一心一意作IO,对于一个普通的动态网页来说,逻辑处理可能只有一小部分,大量的图片等静态
FastCGI缺点:说完了好处,也来说说缺点。从我的实际使用来看,用FastCGI模式更适合生产环境的服务器。但对于开发用机器来说就不太合适。因为当使用ZendStudio调试程序时,由于FastCGI会认为PHP进程超时,从而在页面返回500错误。这一点让人非常恼火,所以我在开发机器上还是换回了ISAPI模式。
安装php路径是/usr/local/php/
1)安装mod_fastcgi
wgethttp://www.fastcgi.com/dist/mod_fastcgi-2.4.6.tar.gz
tarzxvfmod_fastcgi-2.4.6.tar.gz
cdmod_fastcgi-2.4.6
cpMakefile.AP2Makefile
viMakefile,编辑top_dir=/usr/local/httpd
make
makeinstall
安装完后,
/usr/local/httpd/modules/多出一个文件:mod_fcgid.so
2)重新编译php
./configure--prefix=/usr/local/php--enable-fastcgi--enable-force-cgi-redirect--disable-cli
make
makeinstall
这样编译后,在PHP的bin目录下的php-cgi就是fastcgi模式的php解释器了
安装成功后,执行
php-v输出
PHP5.3.2(cgi-fcgi).
这里输出带了cgi-fcgi
2 如果编译时不加--disable-cli则输出PHP5.3.2(cli)
3)配置apache
需要配置apache来以fastcgi模式运行php程序
vihttpd.conf
我们使用虚拟机的方式实现:
#加载fastcgi模块
LoadModulefastcgi_modulemodules/mod_fastcgi.so
#//以静态方式执行fastcgi启动了10进程
FastCgiServer/usr/local/php/bin/php-cgi -processes10-idle-timeout150-pass-headerHTTP_AUTHORIZATION
<VirtualHost*:80>
#
DocumentRoot /usr/local/httpd/fcgi-bin
ServerNamewww.fastcgitest.com
ScriptAlias/fcgi-bin/ /usr/local/php/bin/ #定义目录映射/fcgi-bin/代替/usr/local/php/bin/
Options+ExecCGI
AddHandlerfastcgi-script.php.fcgi#.php结尾的请求都要用php-fastcgi来处理
AddTypeapplication/x-httpd-php.php#增加MIME类型
Actionapplication/x-httpd-php/fcgi-bin/php-cgi #设置php-fastcgi的处理器:/usr/local/php/bin/php-cgi
<Directory/usr/local/httpd/fcgi-bin/>
OptionsIndexesExecCGI
Orderallow,deny
allowfromall
</Directory>
</VirtualHost>
或者
<IfModulemod_fastcgi>ScriptAlias/fcgi-bin/"/usr/local/php/bin"#定义目录映射FastCgiServer/usr/local/php/bin/php-cgi -processes10#配置fastcgiserver,<Directory"/usr/local/httpd/fcgi-bin/">SetHandlerfastcgi-scriptOptionsFollowSymLinksOrderallow,denyAllowfromall</Directory>AddTypeapplication/x-httpd-php.php #增加MIME类型AddHandlerphp-fastcgi.php #.php结尾的请求都要用php-fastcgi来处理Actionphp-fastcgi/fcgi-bin/php-cgi#设置php-fastcgi的处理器
</IfModule>
4).restart下apache,查看phpinfo,如果服务器信息是:
Apache/2.2.11(Unix)mod_fastcgi/2.4.6之类的就说明安装成功了。
如果出现403的错误,查看下/usr/local/httpd/fcgi-bin/是否有足够的权限。
或者
<Directory/>
OptionsFollowSymLinks
AllowOverrideNone
Orderdeny,allow
Denyfromall
</Directory>
改为:
<Directory/>
OptionsFollowSymLinks
AllowOverrideNone
Orderallow,deny
Allowfromall
</Directory>
就可以了。
ps-ef|grep php-cgi可以看见10个fastcgi进程在跑。
phpscript.php
php-fscript.php
以上两种方法(使用或不使用-f参数)都能够运行脚本的script.php。您可以选择任何文件来运行,您指定的PHP脚本并非必须要以.php为扩展名,它们可以有任意的文件名和扩展名。
php-r"print_r(get_defined_constants());"
在使用这种方法时,请您注意外壳变量的替代及引号的使用。
注:请仔细阅读以上范例,在运行代码时没有开始和结束的标记符!加上-r参数后,这些标记符是不需要的,加上它们会导致语法错误。
以上用法给我们提供了非常强大的功能,使得我们可以如下范例所示,动态地生成PHP代码并通过命令行运行这些代码:
$some_application|some_filter|php|sort-u>final_output.txt
除了这种启动时的加载方式,Apache的模块可以在运行的时候动态装载,这意味着对服务器可以进行功能扩展而不需要重新对源代码进行编译,甚至根本不需要停止服务器。我们所需要做的仅仅是给服务器发送信号HUP或者AP_SIG_GRACEFUL通知服务器重新载入模块。但是在动态加载之前,我们需要将模块编译成为动态链接库。此时的动态加载就是加载动态链接库。Apache中对动态链接库的处理是通过模块mod_so来完成的,因此mod_so模块不能被动态加载,它只能被静态编译进Apache的核心。这意味着它是随着Apache一起启动的。
Apache是如何加载模块的呢?我们以前面提到的mod_php5模块为例。首先我们需要在Apache的配置文件httpd.conf中添加一行:
该运行模式是我们以前在windows环境下使用apache服务器经常使用的,而在模块化(DLL)中,PHP是与Web服务器一起启动并运行的。(是apache在CGI的基础上进行的一种扩展,加快PHP的运行效率)
LoadModulephp5_modulemodules/mod_php5.so
这里我们使用了LoadModule命令,该命令的第一个参数是模块的名称,名称可以在模块实现的源码中找到。第二个选项是该模块所处的路径。如果需要在服务器运行时加载模块,可以通过发送信号HUP或者AP_SIG_GRACEFUL给服务器,一旦接受到该信号,Apache将重新装载模块,而不需要重新启动服务器。
A、如上面所说该两种结构都采用FastCGI对PHP支持,因此HTTPServer完全解放出来,可以更好地进行响应和并发处理。因此lighttpd和nginx都有small,butpowerful和efficient的美誉。
B、该两者还可以分出一个好坏来,spawn-fcgi由于是lighttpd的一部分,因此安装了lighttpd一般就会使用spawn-fcgi对php支持,但是目前有用户说ligttpd的spwan-fcgi在高并发访问的时候,会出现上面说的内存泄漏甚至自动重启fastcgi。即:PHP脚本处理器当机,这个时候如果用户访问的话,可能就会出现白页(即PHP不能被解析或者出错)。
另一个:首先nginx不像lighttpd本身含带了fastcgi(spawn-fcgi),因此它完全是轻量级的,必须借助第三方的FastCGI处理器才可以对PHP进行解析,因此其实这样看来nginx是非常灵活的,它可以和任何第三方提供解析的处理器实现连接从而实现对PHP的解析(在nginx.conf中很容易设置)。nginx可以使用spwan-fcgi(需要一同安装lighttpd,但是需要为nginx避开端口,一些较早的blog有这方面安装的教程),但是由于spawn-fcgi具有上面所述的用户逐渐发现的缺陷,现在慢慢减少使用nginx+spawn-fcgi组合了。
C、由于spawn-fcgi的缺陷,现在出现了新的第三方(目前还是,听说正在努力不久将来加入到PHPcore中)的PHP的FastCGI处理器,叫做PHP-FPM(具体可以google)。它和spawn-fcgi比较起来有如下优点:
由于它是作为PHP的patch补丁来开发的,安装的时候需要和php源码一起编译,也就是说编译到phpcore中了,因此在性能方面要优秀一些;
同时它在处理高并发方面也优于spawn-fcgi,至少不会自动重启fastcgi处理器。具体采用的算法和设计可以google了解。
因此,如上所说由于nginx的轻量和灵活性,因此目前性能优越,越来越多人逐渐使用这个组合:nginx+PHP/PHP-FPM
HTTPServer这块基本可以看到有三种stack比较流行:
(2)lighttp+spawn-fcgi
(3)nginx+PHP-FPM
三者后两者性能可能稍优,但是Apache由于有丰富的模块和功能,目前来说仍旧是老大。有人测试nginx+PHP-FPM在高并发情况下可能会达到Apache+mod_php5的5~10倍,现在nginx+PHP-FPM使用的人越来越多。
相关文章
- php实现自动开启/关闭夜间模式
- php 数组根据值找key,从数组查找key对应的值 – key
- PHP编译参数configure配置详解,以及php.ini说明
- PHP缓存类详解编程语言
- 【PHP释放MySQL的威力】(php释放mysql)
- 数据快速学习:使用 PHP 读取 MySQL 数据(php读取mysql)
- PHP与MySQL:搭建你的Web应用(php和mysql)
- 深入学习:PHP如何配置MySQL(php如何配置mysql)
- 数据深入了解:PHP查询MySQL数据库(php显示mysql)
- 数据库MySQL 数据库的 PHP 扩展研究(php扩展mysql)
- 搭建 PHP 环境,在 Linux 系统里更轻松!(php环境linux)
- PHP与MySQL连接失败如何解决?(php连接不上mysql)
- 深入探索:Linux 系统下 PHP 的适用与优势(Linux中php)
- MySQL连接池:PHP提供的快速访问方式(mysql连接池php)
- 使用PHP驱动程序实现与SQL Server数据库的连接(php连接sqlserver)
- PHP与MSSQL的良好配合,助力数据应用升级(php_mssql)
- Linux 系统下PHP升级提升性能(linux 升级 php)
- MSSQL 数据库在PHP中的登录实现(mssql登录php)
- PHP如何连接MySQL数据库?(php如何连接mysql数据库)
- Linux下编译安装PHP:一步步走向稳定性(linux编译安装php)
- Linux下轻松执行PHP文件的方法(linux执行php文件)
- PHP操作Redis队列实现数量控制(redis队列数量php)
- 简体中文转换为繁体中文的PHP函数
- PHP读取文件的正确方法
- 一步一步学习PHP(4)php函数补充2
- php中的观察者模式
- php设计模式Proxy(代理模式)
- PHP基于Yii框架中使用smarty模板的方法详解
- PHP设计模式之结构模式的深入解析
- PHP设计模式之责任链模式的深入解析
- PHP设计模式之解释器模式的深入解析