PHP工做原理及五大运行模式:包括cgi 、fast-cgi、cli、isapi、Web模块模式

PHP的五大运行模式php

 

1)CGI( Common Gateway Interface):即通用网关接口,java

 

2)FastCGI( Long-Live CGI):即常驻型通用网关接口nginx

 

3)CLI( Command Line Interface):即命令行运行接口c++

 

4)Web模块模式(Apache等Web服务器运行的模式) web

 

5)ISAPI(Internet Server Application Program Interface)apache

 

 

 

 

 

 

 

 

1.1 CGI是一种让客户端(web浏览器)与Web服务器(nginx等)程序进行通讯(数据传输)的协议。编程

1)用来规范web服务器传输到php解释器中的数据类型以及数据格式,包括URL、查询字符串、POST数据、HTTP header等,也就是为了保证web server传递过来的数据是标准格式的。浏览器

2)CGI能够用任何一种具备标准输入、输出和环境变量的语言编写,如php、perl、tcl等。不一样类型语言写的程序只要符合cgi标准,就能做为一个cgi程序与web服务器交互,早期的cgi大多都是c或c++编写的。tomcat

3)通常说的CGI指的是用各类语言编写的能实现该功能的程序。安全

1.2.CGI程序的工做原理

1)每次当web server收到index.php这种类型的动态请求后,会启动对应的CGI程序(PHP的解析器);
2)PHP解析器会解析php.ini配置文件,初始化运行环境,而后处理请求,处理完成后将数据按照CGI规定的格式返回给web server而后退出进程;
3)最后web server再把结果返回给浏览器。

1.3 fpm进程管理器是什么?

进程管理器,顾名思义就是管理进程的一个“进程”;

什么意思呢?当咱们接到一个请求时,webserver须要和php进行通讯;

通讯时会成一个主进程,咱们把它理解为一个工厂,主进程下会生成子进程去作具体的运算,咱们把它理解为工人;

也就是说,工厂的做用是调度,是给工人提供工做的一个平台,工人的做用是去作工做。

1.4 CGI程序的特色

1)高并发时的性能较差:
     CGI程序的每一次web请求都会有启动和退出过程,也就是最为人诟病的fork-and-execute模式(每次HTTP服务器遇到动态请求时都须要从新启动脚本解析器来解析php.ini,从新载入所有DLL扩展并重初始化所有数据结构,而后把结果返回给HTTP服务器),很明显,这样的接口方式会致使php的性能不好,在处理高并发访问时,几乎是不可用的。
2)传统的CGI接口方式安全性较差

3)CGI对php.ini的配置很敏感,在开发和调试的时候至关方便

 

CGI已是比较老的模式了,这几年都不多用了。 CGI为每一次请求增长一个进程,效率很低,因此基本已经不在生产部署时采用。但因为CGI对php配置的敏感性,一般被用在开发和调试阶段。

经过CGI程序的工做原理能够看出:CGI程序性能较差,安全性较低,为了解决这些问题产生了FastCGI。

 

php为例,我将一次动态请求相关的概念大体都简单解释一遍。

  1. cgi:它是一种协议。经过cgi协议,web server能够将动态请求和相关参数发送给专门处理动态内容的应用程序。
  2. fastcgi:也是一种协议,只不过是cgi的优化版。cgi的性能较烂,fastcgi则在其基础上进行了改进。
  3. php-cgi:fastcgi是一种协议,而php-cgi实现了这种协议。不过这种实现比较烂。它是单进程的,一个进程处理一个请求,处理结束后进程就销毁。
  4. php-fmp:是对php-cgi的改进版,它直接管理多个php-cgi进程/线程。也就是说,php-fpm是php-cgi的进程管理器所以它也算是fastcgi协议的实现。在必定程度上讲,php-fpm与php的关系,和tomcat对java的关系是相似的。
  5. cgi进程/线程:在php上,就是php-cgi进程/线程。专门用于接收web server的动态请求,调用并初始化zend虚拟机
  6. cgi脚本:被执行的php源代码文件。
  7. zend虚拟机:对php文件作词法分析、语法分析、编译成opcode,并执行。最后关闭zend虚拟机。
  8. cgi进程/线程和zend虚拟机的关系:cgi进程调用并初始化zend虚拟机的各类环境。

以php-fpm为例,web server从转发动态请求到结束的过程大体以下:

 

 

 

而每一个php-cgi进程的做用大体包括:(有些功能分类错误,请无视,知道大体功能就够了)

 

 

 

注意,尽管php-fpm的全称为PHP FastCGI Process Manager,但严格地讲,php-fpm不是fastcgi的进程管理器,而是php fastcgi即php-cgi的进程管理器。fastcgi只是一种协议,不是进程。就像http协议同样,apache对它的实现是httpd,nginx对它的实现就叫nginx。

再次说明,cgi和fastcgi是一种协议。各类支持和WEB交互的编程语言对cgi/fastcgi协议都作了各自的实现(固然,任何一种语言都能写cgi脚本),而php上的php-cgi和php-fpm正是php对fastcgi协议的实现。

 

使用CGI模式时

使用CGI模式时,当动态请求到达,httpd临时启动一个cgi解释器,并经过cgi协议转发要运行的内容。当cgi脚本运行结束后,将结果返回给httpd,而后cgi解释器进程自我销毁。当多个动态请求到达时,将前后启动多个cgi解释器。所以,这种方法效率极低。

在注释掉php5_module的LoadModule相关行后,使用action指令指定要使用cgi运行的类型。但注意,action指令是mod_action提供的,因此必须已经加载该模块。

例如:指定MIME类型为image/gif的请求使用images.cgi运行。显然,images.cgi脚本你必须先写好。

Action image/gif /cgi-bin/images.cgi

还能够经过添加handler来复合文件类型,再使用某个cgi脚本去运行这个handler中的任意类型。

AddHandler my-file-type .xyz
Action my-file-type "/cgi-bin/program.cgi"

对于php来讲,则可使用安装php时bin目录下提供的php-cgi程序做为cgi程序。

[root@xuexi php]# ls /usr/local/php/bin/
pear  peardev  pecl  phar  phar.phar  php  php-cgi  php-config  phpize

# 复制到apache默认的cgi-bin目录下,方便管理
[root@xuexi php]# cp /usr/local/php/bin/php-cgi /usr/local/apache/cgi-bin/

# 在httpd.conf中添加如下行
Action application/x-httpd-php /usr/local/php/bin/cgi-bin/php-cgi

 

使用模块方式时

在编译php时,将php5_module模块编译到apache中,例如在编译php时在./configure配置中加上"--with-apxs2=/usr/local/apache/bin/apxs"。

这种交互模式下,httpd在启动时加载并激活php_module。也就是说,php-cgi常驻在httpd进程内部。当动态请求到达时,httpd不用再生成cgi解释器,而是直接将动态请求转发给它内部php-cgi。

配置实用这种交互模式很是简单,只需使用LoadModule加载php_module,再添加对应的MIME处理器便可。

LoadModule php5_module modules/libphp5.so

# 在mime模块中添加对应的类型
<IfModule mime_module>
AddType application/x-httpd-php .php
AddType applicaiton/x-httpd-php-source .phps
</IfModule>

 

使用php-fpm方式时

前面说了,php-fpm是php-cgi的进程管理器。这种交互方式其实是让php-cgi以独立于httpd的方式存在,目前基本使用php-fpm的方式管理php-cgi进程。也就是说,这种模式下,php-cgi和httpd已经分离了,它们的分离意味着请求的动静分离变为可能:httpd和php-fpm分别运行在不一样服务器上。动静分离后,压力也分散到各自的服务器上。

要让php-fpm以这种方式运行,须要在编译的./configure配置选项中添加"--enable-fpm"选项。固然,还得启动php-fpm服务。例如:

service php-fpm start

这样php-cgi进程就开放着端口(默认9000)等待httpd转发动态请求。要让httpd可以转发请求到php-cgi上,须要在httpd.conf中关闭正向代理,并设置fastcgi协议代理参数。例如,转发到192.168.100.54主机上的php-fpm。

# 加载代理模块
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

# 添加MIME类型
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

# 在须要转发的虚拟主机中配置转发代理
ProxyRequests off
ProxyPassMatch ^/(.*\.php)$ fcgi://192.168.100.54:9000/usr/local/apache/htdocs/$1

 

随着技术的不断升级,单纯的Apache加php模块的方式已再也不主流,而是替换为Apache加php_cgi,以及后来的php_fcgi和nginx加php-fpm的方法,能够看下图

 

 

2.1 CLI模式 

   PHP-CLI是PHP Command Line Interface的简称,如同它名字的意思,就是PHP在命令行运行的接口,区别于在Web服务器上运行的PHP环境(PHP-CGI,ISAPI等)。 也就是说,PHP不单能够写前台网页,它还能够用来写后台的程序。 PHP的CLI Shell脚本适用于全部的PHP优点,使建立要么支持脚本或系统甚至与GUI应用程序的服务端,在Windows和Linux下都是支持PHP-CLI模式的。   

【优势】 

1)使用多进程,子进程结束之后,内核会负责回收资源; 

2)使用多进程,子进程异常退出不会致使整个进程Thread退出,父进程还有机会重建流程; 

3)一个常驻主进程,只负责任务分发,逻辑更清楚。 

   咱们在Linux下常用"php –m"查找PHP安装了那些扩展就是PHP命令行运行模式;有兴趣的同窗能够输入"php –h"去深刻研究该运行模式。 

相关文章
相关标签/搜索