一个用户的Request是如何经过Web服务器(Apache,Nginx,IIS,Light)与后端的动态语言(如PHP等)进行交互并将结果返回给用户的呢?

本文浅谈个人观点,可能有误,欢迎拍砖,共同学习。

一. 首先明确几个概念,以便后续说明

CGI:(Common Gateway Interface)Http服务器与后端程序(如PHP)进行交互的中间层。

工作原理及处理方式(fork-and-execute模式):

1.当Web Server有Request到达

2.fork一个CGI进程或线程(配置管理,环境初始化)

3.执行后台脚本

4.将结果返回Web服务器。

5.Web服务器将结果返回给用户。

FastCGI:常驻型(long-live)CGI形式,经过激活后,不会每次都要花时间去fork。

工作原理及处理方式:

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进程管理器分配的其他请求。

PHP-FPM:只用于PHP的PHP FastCGI 进程管理器。

PHP5.3.3以后的版本已经集成了PHP-FPM了。

php-fpm提供了更好的PHP配置管理方式,可以有效控制内存和进程、可以平滑重载php配置。

./configure php源码的时候,加—enable-fpm参数可开启PHP_FMP。

Spawn-FCGI:一个普通的FastCGI进程管理器。

二. PHP中的CGI实现:

PHP的CGI实现本质上是以Socket编程实现一个TCP或者UDP协议服务器。当启动时, 创建TCP/UDP协议的服务器监听,并接受相关请求进行处理。

CGI的生命周期为:模块初始化;SAPI初始化;请求的处理;模块关闭;SAPI关闭;

以TCP协议为例,在TCP的服务端,会执行如下操作:

1.服务端调用Socket函数创建一个TCP用的流式套接字;

2.服务端调用bind函数将服务器的本地地址与前面创建的套接字绑定;

3.服务调用listen函数将新创建的套接字作为监听,等待客户端发起连接,当客户端有多个连接连接到这个套接字时,可能需要排队处理;

4.服务器调用accept函数进入阻塞状态,直到有客户进程调用connect函数而建立起一个连接;

5.当与客户端创建连接后,服务器调用read_stream函数读取客户的请求;

6.处理完数据后,服务器调用write函数向客户端发送应答。

三.目前PHP的工作方式(以Apache服务器为例,因为Apache和Php是好兄弟嘛)

1.Apache Handler方式(php作为Apache服务器的Module)

一种改进的CGI方式,把PHP的解释模块编成so扩展,添加到Apache的modules中。

配置方式:

1.编译PHP时,加上如下参数:

cd php-source

./configure --prefix=/home/weiyanyan/local/php --with-apxs2=/home/weiyanyan/local/apache/bin/apxs --with-mysql

说明:—with-apxs2为apache中apxs相应目录,将在apache根目录下的modules下生成libphp5.so

2.在apache的配置文件http.conf中增加

LoadModule php5_module modules/libphp5.so

然后在<IfModule mime_module>节点下增加如下mime配置

AddType application/x-httpd-php .php

2.CGI模式

前提为不能以模块模式运行。(注释掉:LoadModule php5_module modules/libphp5.so)

在httpd.conf增加action:

Action application/x-httpd-php /cgi-bin/php-cgi

如果在/cgi目录找不到php-cgi,可从php的bin里面cp一个。

【可以写一个PHP脚本,让其sleep(20);运行之前看机器进程中无php-cgi进程,请求的时候,会有相应的进程产生。经测试一个php-cgi进程可以承载多个请求,具体未深究,因为这种方式已经基本没有人用了。】

3.FastCGI模式

FastCGI模式根据进程管理器的不同可以分为:Apache内置进程管理器,php-fpm进程管理器

Apache内置进程管理器:

mod_fastcgi的安装

#wget http://www.fastcgi.com/dist/mod_fastcgi-2.4.6.tar.gz

# tar -zxvf mod_fastcgi-2.4.6.tar.gz

# cd mod_fastcgi-2.4.6

# cp Makefile.AP2 Makefile

# vim Makefile 将Makefile中的路径改成你的apache的安装路径

# make install 安装成功

安装成功后,会自动把mod_fastcgi.so复制到/usr/local/apache/modules目录

首先要添加fastcgi模块到httpd.conf配置文件:

LoadModule fastcgi_module modules/mod_fastcgi.so

这种模式注释不注释LoadModule php5_module modules/libphp5.so这行貌似没什么关系,只要配置了以下模块

<IfModule fastcgi_module>
   FastCgiServer /home/weiyanyan/local/apache/cgi-bin/php-cgi -processes 20
   AddType application/x-httpd-php .php

AddHandler php-fastcgi .php

Action php-fastcgi /cgi-bin/php-cgi
</IfModule>

就会自动走到fastcgi模式。

然后重启apache,这个时候用 ps aux|grep php就会发现有很多php-cgi进程在运行。说明配置生效.

FPM方式

首先要添加fastcgi模块到httpd.conf配置文件:

LoadModule fastcgi_module modules/mod_fastcgi.so

这种模式注释不注释LoadModule php5_module modules/libphp5.so这行貌似没什么关系,只要配置了以下模块

<IfModule fastcgi_module>
FastCgiExternalServer /home/weiyanyan/local/apache/cgi-bin/php-cgi -host 127.0.0.1:9000

AddType application/x-httpd-php .php

AddHandler php-fastcgi .php

Action php-fastcgi /cgi-bin/php-cgi
</IfModule>

其中在本机9000端口开启了PHP-Fpm服务

FPM的安装简单介绍如下:

cd php-source

./configure --prefix=/home/weiyanyan/local/php --with-apxs2=/home/weiyanyan/local/apache/bin/apxs --with-mysql --enable-fpm

此时在Php的根目录sbin下会有php-fpm运行程序,其配置文件在php根目录下面的/etc/php-fpm.conf

修改完配置,在apache配置对应的端口启动php-fpm即可。

[只是写完,未检查,回家过年…]

参考:

http://www.phppan.com/2011/05/php-cgi/

http://www.cnblogs.com/fangbo/archive/2011/12/02/2272400.html

http://blog.zyan.cc/nginx_php_v6/

Web服务器和动态语言如何交互--CGI&FastCGI&FPM浅谈的更多相关文章

  1. web服务器和后端语言的关系

    1.web服务nginx和php的相互关系  : https://www.cnblogs.com/luckylihuizhou/p/6387171.html 个人理解:web服务器本身没有处理后端语言 ...

  2. Web服务器处理动态程序三种方式及Apache配置

    模块.CGI.FastCGI三种方式介绍 以PHP脚本为例: 模块方式是指Web服务器通过libphp5.so模块调用PHP服务,模块将相关函数嵌入Web服务请求处理流程,不需要额外解释器进程.注意, ...

  3. 实现简易Web服务器(c语言)

    任务: (1)实现服务器与客户端间的通信. (2)可以实现HTTP请求中的GET方法. (3)提供静态网页浏览功能,如可浏览:HTML页面,无格式文本,常见图像格式等. (4)提供可以传递参数的动态网 ...

  4. mini-web框架-WSGI-mini-web框架-web服务器集成动态请求的功能(5.1.2)

    @ 目录 1.说明 2.代码 关于作者 1.说明 WSGI是一个协议 WSGI如下图 浏览器请求动态页面的过程如下 2.代码 WSGI在python实现的关键代码如下 env是用来交互数据的 deal ...

  5. h5课件是什么?h5(html5)怎样实现交互动画开发?-----浅谈h5交互动画课件的优势

    目前很多交互课件,尤其幼儿类的交互课件以动画和交互相结合的类型居多,越来越多的教育机构发现了这种课件对于幼儿的吸引力远大于其他类型的课件,随着flash逐渐被市场淘汰,动画和交互相结合的html5跨平 ...

  6. web服务器/应用服务器/http服务器/中间件

    web服务器:只处理html静态页面不处理动态页面,如apache/nginx/iis等. 应用服务器:能处理html静态页面也能处理动态页面,如tomcat/weblogic/websphere/j ...

  7. Python的Web编程[1] -> Web服务器[0] -> Web 服务器与 CGI / WSGI

    Web服务器 / Web Server 对于Web来说,需要建立一个Web服务器,必须建立一个基本的服务器和一个处理程序, 基本服务器的主要作用是,在客户端和服务器端完成必要的HTTP交互, 处理程序 ...

  8. Servlet学习笔记【1】--- 背景和基础知识(CGI、Web服务器发展史、Servlet简介、任务、继承结构)

    本文主要讲Servlet的基础知识和背景知识. 1 CGI简介 CGI(Common Gateway Interface 公共网关接口)是WWW技术中最重要的技术之一,有着不可替代的重要地位.CGI是 ...

  9. 关于嵌入式web服务器

    1.boa的配置文件boa.conf Port 80 //服务访问端口 User 0 Group 0 ErrorLog /var/log/boa/error_log //错误日志地址 AccessLo ...

随机推荐

  1. DOM2定位与高宽类属性专题学习【DOM专题学习系列(一)】

    网页可见区域宽: document.body.clientWidth;网页可见区域高: document.body.clientHeight;网页可见区域宽: document.body.offset ...

  2. php的一些小笔记--数学函数

    通常我们使用的数学函数不多,经常出现的有 floor 地板->舍去 ceil   天花板->进一 round 四舍五入 rand 随机数 mt_rand 产生更好的随机数 pow 指数表达 ...

  3. 超级密码(dfs)

    超级密码233 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  4. SQL Server 无法打开物理文件的 2 种解决办法

    解决方法: 方法1.无法打开可以能是没有权限.如果是这样以管理员身份运行Managerment Studio就可以了. 方法2.找到指定的数据库文件.右键属性-->安全-->勾上  ‘完全 ...

  5. 英文Ubuntu下Emacs 使用 ibus 五笔

    Ubuntu 12.04 Precise 英文版本 1. 安装ibus/安装ibus-table-wubi http://wiki.ubuntu.org.cn/IBus 其中im-switch命令要在 ...

  6. Uubntu scrot 的简单使用

    scrot 是一个使用 imlib2 库截取屏幕和保存图像的的工具. 1:安装 #apt-get install scrot 2:查看帮助 #scrot -help -v, --version显示版本 ...

  7. DataTable Select 使用

    DataView dv = new DataView(table); dv.RowFilter = " Type='10' and Visible='true'"; dv.Sort ...

  8. 剑指offer-面试题5.从尾到头打印链表

    题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. 刚看到这道题的小伙伴可能就会想,这还不简单,将链表反转输出. 但是这种情况破坏了链表的结构. 如果面试官要求不破坏链表结构呢,这时候我们 ...

  9. find -exec

    find -exec 的标准写法 find ./ -name "*.tmp" -exec rm -rf "{}" \; find -exec 这个命令组合很好用 ...

  10. A Simple Problem with Integers(100棵树状数组)

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...