CGI,FastCGI, php-fpm , php_mod

CGI:common gateway interface,通用网关接口。

最初的服务器只能展示静态内容,静态的html,图片等等。随着需求发展,网站变得复杂,需要’动态语言’支持,但是服务器不能直接运行动态脚本(asp,php,python,java等等),这时候需要把动态脚本交给动态语言的解释器或者编译器去执行,然后拿到执行结果,返回给浏览器。但是动态语言众多,服务器软件和解释器/编译器之间不能每个都做定制化的数据传输规定,所以要做一套标准的协议,这就是CGI,它是一种协议,依照CGI协议去编写的程序即为CGI程序/应用/脚本。 

CGI接口标准包括标准输入、环境变量、标准输出三部分。
1.标准输入
  CGI程序像其他可执行程序一样,可通过标准输入(stdin)从Web服务器得到输入信息,如Form中的数据,这就是所谓的向CGI程序传递数据的POST方法。这意味着在操作系统命令行状态可执行CGI程序,对CGI程序进行调试。POST方法是常用的方法。
2.环境变量
  操作系统提供了许多环境变量,它们定义了程序的执行环境,应用程序可以存取它们。Web服务器和CGI接口又另外设置了自己的一些环境变量,用来向CGI程序传递一些重要的参数。CGI的GET方法还通过环境变量QUERY-STRING向CGI程序传递Form中的数据。
3.标准输出
  CGI程序通过标准输出(stdout)将输出信息传送给Web服务器。传送给Web服务器的信息可以用各种格式,通常是以纯文本或者HTML文本的形式,这样我们就可以在命令行状态调试CGI程序,并且得到它们的输出。

这里写图片描述

服务器通过标准输入把数据传给CGI程序,CGI程序通过标准输出把数据返回给服务器,并且CGI程序运行期间可以使用一些系统环境变量,这些标准输入(STDIN)和标准输出(STDOUT)以及环境变量,都是遵循CGI协议。

这里写图片描述

有了CGI协议和CGI脚本,那脚本需要有个运行模式

正常情况下,服务器接受一个请求,产生一个CGI程序的解释器进程,解释器运行脚本,返回结果给服务器,进程关闭,服务器把结果返回给浏览器。

如果访问量增大,进程的创建和关闭将会耗费巨大的系统资源,显然普通的运行模式不能满足高访问的需求。

FastCGI应需求而生
以PHP为例,PHP解析器会解析php.ini文件,初始化执行环境。普通的运行模式下,服务器对每个请求都会执行这些步骤,所以处理每个时间的时间会比较长。
相比普通的CGI程序运行模式,FastCGI会提高性能
首先,Fastcgi会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是fastcgi的对进程的管理。

至此以上皆为,协议或者模式,与脚本语言无关,但是最终协议/模式的实现需要载体。


PHP-FPM即为实现fastCGI的进程
Nginx和PHP-fpm是一对好基友,使用过的同学都知道,如果要在Nginx下运行PHP,除了要开启Nginx服务,还要开启一个php-fpm服务。并且在开启两个服务前需要配置Nginx,其中Nginx中有几行配置:

location ~ .php$ {
    root html;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket,(这个socket可以是文件socket,也可以是ip socket)。

fastcgi_pass 127.0.0.1:9000;

注明了socket接口的地址。而在php-fpm中配置了,php-fpm的进程端口即为9000。
二者端口一样,Nginx和php-fpm就绑定了,之后所有的动态脚本都会去转给9000端口即php-fpm处理。
当开启php-fpm的时候,通过ps -ef |grep fpm
这里写图片描述
emmmm、和前面介绍的fastCGI一毛一样。

Nginx是把动态请求转给第三方(php-fpm)处理,而Apache可以把第三方’收入囊中’,这就是php_mod
Apache的配置文件中有‘加载模块’的配置,如果要运行PHP,那必不可少的一行配置是
win下:

LoadModule php5_module C:/php/php5apache2_2.dll

linux下:

LoadModule php5_module modules/libphp5.so

这里的配置项即为,将PHP以Apache模块的方式运行,如果我们在Apache启动前在其配置文件中配置好了PHP模块, PHP模块通过注册apache2的ap_hook_post_config挂钩,在Apache启动的时候启动此模块以接受PHP文件的请求。

Apache 的Hook机制是指:
Apache 允许模块(包括内部模块和外部模块,例如mod_php5.so,mod_perl.so等)将自定义的函数注入到请求处理循环中。
换句话说,模块可以在Apache的任何一个处理阶段中挂接(Hook)上自己的处理函数,从而参与Apache的请求处理过程。 
mod_php5.so/ php5apache2.dll就是将所包含的自定义函数,通过Hook机制注入到Apache中,在Apache处理流程的各个阶段负责处理php请求。

Apache一般会采用多进程模式, Apache启动后会fork出多个子进程,每个进程的内存空间独立,每个子进程都会经过开始和结束环节, 不过每个进程的开始阶段只在进程fork出来以来后进行,在整个进程的生命周期内可能会处理多个请求。 只有在Apache关闭或者进程被结束之后才会进行关闭阶段,在这两个阶段之间会随着每个请求重复请求开始-请求关闭的环节。
这里写图片描述
多线程模式和多进程中的某个进程类似,不同的是在整个进程的生命周期内会并行的重复着 请求开始-请求关闭的环节.
在这种模式下,只有一个服务器进程在运行着,但会同时运行很多线程,这样可以减少一些资源开销,向Module init和Module shutdown就只需要运行一遍就行了,一些全局变量也只需要初始化一次,因为线程独具的特质,使得各个请求之间方便的共享一些数据成为可能。
多线程工作方式如下图
这里写图片描述
Apache一般使用多进程模式prefork
在linux下使用#http –l 命令可以查看当前使用的工作模式。也可以使用#apachectl -l命令。
看到的prefork.c,说明使用的prefork工作模式。
prefork 进程池模型,用在 UNIX 和类似的系统上比较多,主要是由于写起来方便,也容易移植,还不容易出问题。要知道,如果采用线程模型的话,用户线程、内核线程和混合型线程有不同的特性,移植起来就麻烦。prefork 模型,即预先 fork() 出来一些子进程缓冲一下,用一个锁来控制同步,连接到来了就放行一个子进程,让它去处理。
prefork MPM 使用多个子进程,每个子进程只有一个线程。每个进程在某个确定的时间只能维持一个连接。在大多数平台上,Prefork MPM在效率上要比Worker MPM要高,但是内存使用大得多。prefork的无线程设计在某些情况下将比worker更有优势:他能够使用那些没有处理好线程安全的第三方模块,并 且对于那些线程调试困难的平台而言,他也更容易调试一些。
无论那种模式,其本质都是和fastCGI的目的一样,一次性加载,多个进程常驻。
相关链接:
http://blog.csdn.net/chuanzhilong/article/details/52868737
https://segmentfault.com/a/1190000007322358
https://www.cnblogs.com/liuzhang/p/3929198.html
http://blog.csdn.net/hguisu/article/details/7377520

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值