12.PHP内核探索:PHP的FastCGI

CGI全称是“通用网关接口”(Common Gateway Interface), 它可让一个客户端,从网页浏览器向执行在Web服务器上的程序请求数据。 CGI描述了客户端和这个程序之间传输数据的一种标准。 CGI的一个目的是要独立于任何语言的,因此CGI能够用任何一种语言编写,只要这种语言具备标准输入、输出和环境变量。 如php,perl,tcl等。php

FastCGI是Web服务器和处理程序之间通讯的一种协议, 是CGI的一种改进方案,FastCGI像是一个常驻(long-live)型的CGI, 它能够一直执行,在请求到达时不会花费时间去fork一个进程来处理(这是CGI最为人诟病的fork-and-execute模式)。 正是由于他只是一个通讯协议,它还支持分布式的运算,即 FastCGI 程序能够在网站服务器之外的主机上执行而且接受来自其它网站服务器来的请求。html

FastCGI是语言无关的、可伸缩架构的CGI开放扩展,将CGI解释器进程保持在内存中,以此得到较高的性能。 CGI程序反复加载是CGI性能低下的主要缘由,若是CGI程序保持在内存中并接受FastCGI进程管理器调度, 则能够提供良好的性能、伸缩性、Fail-Over特性等。数据库

通常状况下,FastCGI的整个工做流程是这样的:api

  1. Web Server启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module)
  2. FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可见多个php-cgi)并等待来自Web Server的链接。
  3. 当客户端请求到达Web Server时,FastCGI进程管理器选择并链接到一个CGI解释器。 Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
  4. FastCGI子进程完成处理后将标准输出和错误信息从同一链接返回Web Server。当FastCGI子进程关闭链接时, 请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web Server中)的下一个链接。 在CGI模式中,php-cgi在此便退出了。

PHP的CGI实现了Fastcgi协议,是一个TCP或UDP协议的服务器接受来自Web服务器的请求, 当启动时建立TCP/UDP协议的服务器的socket监听,并接收相关请求进行处理。随后就进入了PHP的生命周期: 模块初始化,sapi初始化,处理PHP请求,模块关闭,sapi关闭等就构成了整个CGI的生命周期。浏览器

以TCP为例,在TCP的服务端,通常会执行这样几个操做步骤:服务器

  1. 调用socket函数建立一个TCP用的流式套接字;
  2. 调用bind函数将服务器的本地地址与前面建立的套接字绑定;
  3. 调用listen函数将新建立的套接字做为监听,等待客户端发起的链接,当客户端有多个链接链接到这个套接字时,可能须要排队处理;
  4. 服务器进程调用accept函数进入阻塞状态,直到有客户进程调用connect函数而创建起一个链接;
  5. 当与客户端建立链接后,服务器调用read_stream函数读取客户的请求;
  6. 处理完数据后,服务器调用write函数向客户端发送应答。

PHP的FastCGI使你的全部php应用软件经过mod_fastci运行,而不是mod_phpsusexec。FastCGI应用速度很快 是由于他们持久稳定,没必要对每个请求都启动和初始化。这使得应用程序的开发成为可能,不然在CGI范例是不切实际的(例如一个大型的脚本,或者一个须要 链接单个或多个数据库的应用)。架构

FastCGI的优势:socket

  1. PHP脚本运行速度更快(3到30倍)。PHP解释程序被载入内存而不用每次须要时从存储器读取,极大的提高了依靠脚本运行的站点的性能。
  2. 须要使用更少的系统资源。因为服务器不用每次须要时都载入PHP解释程序,你能够将站点的传输速度提高很高而没必要增长cpu负担。
  3. 不须要对现有的代码做任何改变。现有的一切都适用于PHP的FastCGI。

可是也会有潜在问题:分布式

  • 对全部的子目录(/home/USERNAME/public_html/php.ini)你只有一个可用的php.ini文件。这是优 化网站代码所必需的。若是你须要多个php.ini文件以适应不一样的脚本须要,你能够在任何子目录禁用PHP的快速CGI,而其他的地方则继续有效。若是 你须要这样作请联系support。
  • 你对PHP环境作的任何升级(如php.ini文件的改变)都有几分钟的延迟。这是由于为了更快的速度你的php.ini文件已经被载入内存,而不是每次须要时再从存储器从新读取。
相关文章
相关标签/搜索