一次明明白白CGI与FASTCGI及php-fpm
目录
概念概述
CGI全称Common Gateway Interface.
CGI
是HTTP Server和一个独立的进程之间的协议,把HTTP Request的Header设置成进程的环境变量,HTTP Request的正文设置成进程的标准输入,而进程的标准输出就是HTTP Response包括Header和正文。
FASTCGI
是和HTTP协议类似的概念。无非就是规定了在同一个TCP连接里怎么同时传多个HTTP连接。这实际上导致了个问题,有个HTTP连接传个大文件不肯让出FASTCGI连接,在同一个FASTCGI连接里的其他HTTP连接就傻了。
php-fpm
就相当于是Apache+mod_php。无非php-fpm自带了FASTCGI Server,而Apache是HTTP Server。
无论你前面是FASTCGI,HTTP,SCGI,uWSGI等协议,你的FASTCGI/HTTP/SCGI/uWSGI Server都以相同的参数格式去调用一个函数,这样你用Python写的Web应用并不需要修改代码,就可以运行在不同的Server后面了。
CGI 发展到 FASTCGI
-
一般web服务器接受到浏览器的请求时,如果是
静态资源
的话就直接将其返回给浏览器,如果是动态资源的话那就没有现成的资源返回了,那这个时候CGI就出场了。 -
CGI可以理解为一种
协议
,就是动态去生成文件,从程序上来理解就是web服务器exec这样一个进程,然后交给他一些输入参数,他就慢慢的处理完后把结果返回给web服务器,那从协议层面来说CGI协议就是规范了web服务器和CGI程序的一些输入输出参数的含义 -
所以可以有很多不同的CGI程序,可以执行php脚本的或是可以执行python脚本的,只要符合这类规范就能供web服务器调用,当然它的缺点就是每次都需要去启动这个CGI程序,这会使得处理速度很慢
-
针对这种缺陷加以改进就成了FASTCGI,同样的也可以理解为一种协议,它跟CGI的不同就是不需要每次去exec,它会事先启动起来,作为一个CGI的管理服务器存在,预先启动一系列的子进程来等待处理,然后等待web服务器发过来的请求,一旦接受到请求就交由子进程处理,这样由于不需要在接受到请求后启动CGI,会快很多。
-
php-fpm是php对FASTCGI的一种具体实现,它的启动后会创建多个CGI子进程,然后主进程负责管理子进程,同时它对外提供一个socket,那web服务器当要转发一个动态请求时只需要按照FASTCGI协议要求的格式将数据发往这个socket的就可以了,那php-fpm创建的子进程去争抢这个socket连接,谁抢到了谁处理并将结果返回给web服务器,那php-fpm主进程干什么了?比方说其中一个子进程异常退出了怎么办,那php-fpm会去监控他一旦发现一个CGI子进程就会又启动一个,还有其他诸多管理功能
-
php-fpm作为一个独立的进程存在,通过socket与nginx建立连接,而mod_php 是作为一个模块被加载进了apache服务器,同时他们两作为CGI调度管理器,他们对其管理的方式也不一样
通俗比喻描述CGI与FASTCGI
通俗的可以把服务器看作餐厅,用户请求看作来用餐的顾客,服务器处理请求看作解决顾客的就餐问题(响应输出一份饭)。
服务器上静态资源
看作已做好的饭,只要放到餐盒里就可以返回给顾客,动态资源
需要厨房大厨现成做份再放到餐盒里返回给顾客。
mod_php
这个大厨有个特点,看见有顾客进门就点火,不管顾客要不要现做的,有点浪费资源
php_fpm
(是FASTCGI的具体实现方式)这个大厨有好多小弟一直点着火(多个处理进程),等有顾客说要现做,大厨就安排小弟做份返回给客户
CGI
也是个大厨,不过他等到顾客要现做,他才点火,做饭,然后熄火。等待下一个要现做的到来
FASTCGI
就是个大厨雇了一帮小弟,专门做需要现场做的饭,大厨只管分派任务,小弟真正操锅做饭
@tsingchan markdown