在apache里,可以以php5_module模块的方式调用php,而在nginx里面,则需要通过php-fpm来调用,这两种调用方式有什么不同?另外,它们跟cgi,fastcgi有什么关系?
回复内容:上面的回答多少都有些问题吧。
cgi是http server和一个独立的进程之间的协议,把http request的header设置成进程的环境变量,http request的正文设置成进程的标准输入,而进程的标准输出就是http response包括header和正文。
fastcgi是和http协议类似的概念。无非就是规定了在同一个tcp连接里怎么同时传多个http连接。这实际上导致了个问题,有个http连接传个大文件不肯让出fastcgi连接,在同一个fastcgi连接里的其他http连接就傻了。所以lighttpd? 引入了 x-sendfile 。
php-fpm就相当于是apache+mod_php。无非php-fpm自带了fastcgi server,而apache是http server。
那个wsgi和这个问题没啥关系吧。wsgi这个只是python内部的一个接口。无论你前面是fastcgi,http,scgi,uwsgi等协议,你的fastcgi/http/scgi/uwsgi server都以相同的参数格式去调用一个函数,这样你用python写的web应用并不需要修改代码,就可以运行在不同的server后面了。无非cgi协议是进程间的,而wsgi是进程内的。b本屌丝路过 也来吹吹牛逼
1. 一般web服务器接受到浏览器的请求时,如果是静态资源的话就直接将其返回给浏览器,如果是动态资源的话那就没有现成的资源返回了,那这个时候cgi就出场了
2. cgi可以理解为一种协议or一类处理程序,就是动态去生成文件,从程序上来理解就是web服务器exec这样一个进程,然后交给他一些输入参数,他就慢慢的处理完后把结果返回给web服务器,那从协议层面来说cgi协议就是规范了web服务器和cgi程序的一些输入输出参数的含义
3.所以可以有很多不同的cgi程序,别可以执行php脚本的or可以执行python脚本的,只要符合这类规范就能供web服务器调用,当然它的缺点就是每次都需要去启动这个cgi程序,这会使得处理速度很慢
4.针对这种缺陷加以改进就成了fastcgi,同样的他也可以理解为一种协议or一个程序,它跟cgi的不同就是不需要每次去exec,它会事先启动起来,作为一个cgi的管理服务器存在,预先启动一系列的子进程来等待处理,然后等待web服务器发过来的请求,一旦接受到请求就交由子进程处理,这样由于不需要在接受到请求后启动cgi,会快很多。
5.phpfpm是php对fastcgi的一种具体实现,它的启动后会创建多个cgi子进程,然后主进程负责管理子进程,同时它对外提供一个socket,那web服务器当要转发一个动态请求时只需要按照fastcgi协议要求的格式将数据发往这个socket的就可以了,那phpfpm创建的子进程去争抢这个socket连接,谁抢到了谁处理并将结果返回给web服务器,那phpfpm主进程干什么了?比方说其中一个子进程异常退出了怎么办,那phpfpm会去监控他一旦发现一个cgi子进程就会又启动一个,还有其他诸多管理功能
6 phpfpm作为一个独立的进程存在 通过socket与nginx建立连接,而mod_php 是作为一个模块被加载进了apache服务器,同时他们两作为cgi调度管理器,他们对其管理的方式也不一样
就说这么多了通俗的可以把服务器看作餐厅,用户请求看作来用餐的顾客,服务器处理请求看作解决顾客的就餐问题(响应输出一份饭)。
服务器上静态资源看作已做好的饭,只要放到餐盒里就可以返回给顾客,动态资源需要厨房大厨现成做份再放到餐盒里返回给顾客。
php_mod这个大厨有个特点,看见有顾客进门就点火,不管顾客要不要现做的,有点浪费资源
php_fpm这个大厨有好多小弟一直点着火(多个处理进程),等有顾客说要现做,大厨就安排小弟做份返回给客户
cgi也是个大厨,不过他等到顾客要现做,他才点火,做饭,然后熄火。等待下一个要现做的到来
fastcgi呢就是个大厨雇了一帮小弟,专门做需要现场做的饭,大厨只管分派任务,小弟真正操锅做饭这个问题可以分两个层面讨论:
1. php 解释器是否嵌入 web 服务器进程内部执行
mod_php 通过嵌入 php 解释器到 apache 进程中,只能与 apache 配合使用,而 cgi 和 fast-cgi 以独立的进程的形式出现,只要对应的web服务器实现 cgi 或者 fast-cgi 协议,就能够处理 php 请求。
mod_php 这种嵌入的方式最大的弊端就是内存占用大,不论是否用到 php 解释器都会将其加载到内存中,典型的就是处理css、js之类的静态文件是完全没有必要加载解释器。
2. 单个进程处理的请求数量
mod_php 和 fast-cgi 的模式在每个进程的生命周期内能够处理多个请求,而 cgi 的模式处理一个请求就马上销毁进程,在高并发的场景下 cgi 的性能非常糟糕。
综上,如果对性能有极高的要求,可以将静态请求和动态请求分开,这时 nginx + php-fpm 是比较好的选择。
ps: cgi、fastcgi 通常指 web 服务器与解释器通信的协议规范,而 php-fpm 是 fastcgi 协议的一个实现。cgi(common gateway interface)
最初,cgi 是在 1993 年由美国国家超级电脑应用中心(ncsa)为 ncsa httpd web 服务器开发的。
这个 web 服务器使用了 unix shell 环境变量 来保存从 web 服务器传递出去的参数,然后生成一个运行 cgi 的独立进程。cgi的第一个实现是 perl 写的[1]。
效率低下:每一个连接 fork 一个进程处理。功能十分有限:cgi只能收到一个请求,输出一个响应。很难在cgi体系去对web请求的控制,例如:用户认证等。正因为这些问题,在cgi诞生后的很长一段时间,各种web server都还是采用api这种强绑定的方式去支持web开发,其中apache的mod_php就属于这种方式。所以后面就有大神提出了fastcgi标准。
fastcgi(fast common gateway interface)
fastcgi使用进程/线程池来处理一连串的请求。这些进程/线程由fastcgi服务器管理,而不是web服务器。 当进来一个请求时,web服务器把环境变量和这个页面请求通过一个socket长连接传递给fastcgi进程。所以fastcgi有如下的优点:
性能:通过进程/线程池规避了cgi开辟新的进程的开销。兼容:非常容易改造现有cgi标准的程序。语言无关:fastcgi是一套标准,理论上讲只要能进行标准输出(stdout)的语言都可以作为fastcgi标准的web后端。
下面是一个简单fastcgi后端的伪代码
void main(void){int count = 0; while(fcgi_accept() >= 0) { printf(“content-type: text/html\r\n”); printf(“\r\n”); printf(“hello world!\r\n”); printf(“request number %d.”, count++); }exit(0);}
cgi 中文翻译是通用网关接口,它是一种通信协议,让脚本语言(比如php)具备和 http server 交互的能力。
fastcgi 是对 cgi 的一种改良,解决了 cgi 协议的一些性能问题,在 php 平台被广泛采用。类似的东西还有 wsgi。
php-fpm 就是fastcgi 的一种实现,附带了进程管理的功能。cgi看rfc3875:https://www.ietf.org/rfc/rfc3875
fastcgi看:fastcgi specification
总的来说fastcgi是对cgi的性能改进,规范上有一些差异但是不大,与浏览器的通信规范是一致的。
php不了解。php 解释器的执行,主要有三者模式,mod_php、cgi、fastcgi。
mode_php 是apache 的一个模块,把php 解释器嵌入到apache 进程中。cgi 和fastcgi 分别是一种协议。web server 实现了cgi 或fastcgi 协议的相应的应用程序(以下简称cgi 或fastcgi),就可以启动php 解释器处理php 请求。它们都是以独立进程的形式存在。mode_php 和fastcgi 在 单个进程中可以处理多个请求,cgi 在单个进程中只能处理一个请求。
php-cgi 是一种cgi 协议的实现。php-cgi 其实就是php 解析器。在cgi 模式时,当web server 收到 xx/index.php 请求时,会启动php-cgi,php-cgi 会解析php.ini 文件,初始化环境,然后根据请求参数进行处理,再返回处理后的结果。(都是以cgi 协议规范来进行)php-cgi 在每个请求时都会启动一个进程,然后读取php.ini 进行解析,可想而知效率相对比较低。php-cgi 无法实现平滑重启。修改php.ini 配置后,后面启动的php-cgi 程序还是不会感知。
php-fpm 即fastcgi process management,是一种fastcgi 协议的实现。当请求到来时,php-fpm 启动并读取php.ini 文件完成初始化环境,然后启动一个master,再启动多个worker。当请求过来时,master 会传递给一个worker,然后等待下一个请求。php-fpm 会动态配置worker 的数量。一个php-fpm 进程可以处理多个请求,会启动多个php-cgi 程序。php-fpm 可以实现平衡重启。修改php.ini 后,当启用新的worker 会使用新的配置。cgi,common gateway interface,通用网关接口。将用户的指令通过它递交给后台进行处理。可以理解为一种通用的协议,能够标准化用户指令,方便后台程序进行后续的处理。
fastcgi根据协议将cgi进行包装,与外部程序如nginx进行通信。一般拥有主从进程。fastcgi可以管理多种语言的cgi,比如题主提到的php,另外还有python、ruby等。可以理解为一种cgi的成熟模型。
而php-fpm是一个很好地实现了fastcgi的程序,后来被php收入官方项目中了。可以理解为fastcgi的管理器。稳定地管理fastcgi进程。