ISAPI、CGI、FASTCGI、PHP-FPM与线程安全、线程非安全

web服务器与PHP的接口类型列表:

/**
* Returns the type of interface between web server and PHP
* @link http://php.net/manual/en/function.php-sapi-name.php
* @return string the interface type, as a lowercase string.
* </p>
* <p>
* Although not exhaustive, the possible return values include
*
aolserver, apache,
*
apache2filter, apache2handler,
*
caudium, cgi(until PHP 5.3),
*
cgi-fcgi, cli,
*
continuity, embed,
*
isapi, litespeed,
*
milter, nsapi,
*
phttpd, pi3web, roxen,
*
thttpd, tux, and webjames.
* @since 4.0.1
* @since 5.0
*/
function php_sapi_name () {}

CGI:通用网关接口(Common Gateway Interface),是个协议,对应语言的实现就是对应的解析器,如PHP解析器php-cgi,工作时会解析php.ini文件,初始化执行环境,然后解释代码再返回响应。本身只能解析请求,返回结果,不会进程管理,所以这种方式的话像平滑启动、多版本并存就无法实现了。

 

ISAPI:Internet Server Application Programming Interface,是种协议,对应语言的实现就是对应的服务器扩展(以动态链接库dll形式存在)。一个ISAPI的DLL,可以在被用户请求激活后长驻内存,等待用户的另一个请求,还可以在一个DLL里设置多个用户请求处理函数,此外,ISAPI的DLL应用程序和WWW服务器处于同一个进程中,效率要显著高于CGI。而且加上辅助工具如ISAPI筛选器,可以将请求先过滤再响应。遗憾的是,ISAPI实现时要用到微软api,所以跨平台性差,只能在 IIS(InternetInformationServer)和MSpersonalwebserver以及NTworkstation上的 peerwebserver上用。

apache模块dll也是类似原理,语言环境随服务器一起启动,常驻内存减少消耗。

注:IIS上一般我们会把PHP配置成以ISAPI的方式来运行,ISAPI是多线程的方式,这样就快多了。但存在一个问题,很多常用的PHP扩展是以Linux/Unix的多进程思想来开发的,这些扩展在ISAPI的方式运行时就会出错搞垮服务器。因此在IIS下CGI模式才是PHP运行的最安全方式,但CGI模式对于每个HTTP请求都需要重新加载和卸载整个PHP环境,其消耗是巨大的。

 

FastCGI:为了兼顾IIS下PHP的效率和安全,微软给出了FastCGI的解决方案。同ISAPI原理有些类似,就是减少CGI初始化等前置操作的消耗。FastCGI可以让PHP的进程重复利用而不是每一个新的请求就重开一个进程。同时FastCGI也可以允许几个进程同时执行。这样既解决了CGI进程模式消耗太大的问题,又利用上了CGI进程模式不存在线程安全问题的优势。那么Fastcgi是怎么做的呢?首先,Fastcgi会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。要说明的是FastCGI本身仅仅是种协议,php-fpm是其中一种实现,来管理cgi程序,其操作比如:

--start 启动php的fastcgi master进程
--stop 强制终止php的fastcgi master进程
--quit 平滑终止php的fastcgi master进程
--restart 重启php的fastcgi master进程
--reload 重新平滑加载php的php.ini
--logrotate 重新启用log文件

 

补充说明:一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同,相当于克隆了一个自己。

 

从2000年10月20日发布的第一个Windows版的PHP3.0.17开始的都是线程安全的版本,这是由于与Linux/Unix系统是采用多进程的工作方式,不同的是Windows系统是采用多线程的工作方式。如果在IIS/Nginx/Apache下以CGI方式运行PHP会非常慢,这是由于CGI模式是建立在多进程的基础之上的,而非多线程。

根据上述几种执行方式的说明可知,如果是使用ISAPI的方式来运行PHP就必须用Thread Safe(线程安全)的版本;而用FastCGI模式运行PHP的话就没有必要用线程安全检查了,用None Thread Safe(NTS,非线程安全)的版本能够更好的提高效率。

posted @ 2016-09-09 17:19 小天儿 阅读(...) 评论(...)  编辑 收藏