php之CGI、FastCGI 和 php-fpm

一、cgi 规范

官方文档:RFC3875: CGI - the Common Gateway Interface`

1. CGI 目的

The Common Gateway Interface (CGI) allows an HTTP server and a CGI script to share responsibility for responding to client requests.

CGI 使得 Http-ServerCGI 程序 可以在 客户端请求提供相应 上分工合作、各司其职。

2. Server 职责

The server acts as an application gateway. It receives the request from the client, selects a CGI script to handle the request, converts the client request to a CGI request, executes the script and converts the CGI response into a response for the client.

Http-Server 作为一个应用网关,负责:

  • 接受http请求
  • 选择一个cgi程序处理http请求
  • 将http请求转化成cgi请求
  • 执行cgi程序
  • 将cgi程序的响应转为为http响应
3. server 发起 CGI 请求

Server 在发起 cgi 请求时,需要从 http 请求中解析到以下信息:

  • Meta-variables: CONTENT_TYPE PATH_INFO REMOTE_ADDR REMOTE_HOST REQUEST_METHOD SCRIPT_NAME SERVER_NAME
  • 请求体:post 数据等
  • 请求方法:GET POST HEAD
  • cgi 程序的执行命令
4. server 解析 CGI 响应
  • 接收 cgi 响应:

cgi 程序通过使用 server 提供的方法 或者 标准输出文件符 将结果返回给 server,同时,server 也会实现一个等待 cgi 返回的超时策略,用来终止超时未返回的 cgi 进程。

  • 解析 cgi 响应类型:

    • document-response,文档响应,如:Content-Type [ Status ] *other-field NL response-bodyserver 会在此基础上做一些改动,以符合 http 协议。
    • local-redir-response,本地重定向响应,如:local-Location NLserver 需要根据此影响,发起另一次的 cgi 请求
    • client-redir-response,客户端重定向响应,如:client-Location *extension-field NL。对于 http 请求,server 需要返回给客户端一个 302 found 的客户端重定向响应。
    • client-redirdoc-response,客户端文档重定向响应,如:client-Location Status Content-Type *other-field NL response-body
  • 解析 cgi 响应头信息:

    • Content-Type,响应类型,如:"Content-Type:" media-type
    • Location,重定向相关头信息,包含:Location client-Location local-Location fragment-URI fragment local-pathquery abs-path 等。
    • Status,处理状态,定义:Status:" status-code SP reason-phrase NL,如:200 'OK'302 'Found'400 'Bad Request'501 'Not Implemented'等。
    • Protocol-Specific Header Fields,协议特殊响应,如:HTTP/1.0HTTP/1.1等。
    • Extension Header Fields,扩展头信息,以 X-CGI- 打头的响应头。
  • 解析 cgi 响应内容:

cgi 响应体的定义是 response-body = *OCTET,server 需要将 cgi 响应体原封不动的返回给客户端,除非 cgi 响应头信息中要求了 transfer-codingscontent-codingscharset conversions 相关的转化。

5. cgi 对 server 的规范要求

define any restrictions on allowed path segments, in particular whether non-terminal NULL segments are permitted;

  • server 要对 允许访问的 path 进行限制

define the behaviour for "." or ".." path segments; i.e., whether they are prohibited, treated as ordinary path segments or interpreted in accordance with the relative URL specification.

  • server 要明确 ... 的处理方式

define any limits of the implementation, including limits on path or search string lengths, and limits on the volume of header fields the server will parse.

  • server 要对 path query_string 头信息数量及长度 进行限制
6. cgi 对 cgi 程序的规范要求
  • 对于无法处理的 path_info 给与 404 Not Found 响应。
  • 对于无法确认 content_type 的表单给与 415 'Unsupported Media Type' 响应。即:不是 application/x-www-form-urlencoded 且不是 multipart/form-data 的表单。
  • 在返回头信息时,cgi 程序应当在 http 头信息之前,尽可能快的返回 cgi 头信息,以便节省 server 的内存使用。
  • cgi 应该明白 REMOTE_ADDRREMOTE_HOST 并不能正确表明请求的最终来源,这些只表明了请求的最近来源,而这个来源可能是代理或者网关。
7. cgi 中的安全考虑
  • gethead 请求方法应该是安全的,幂等的(多次请求和一次请求的效果是一样的)。
  • 对于 http 头信息中包含的 敏感信息,如:HTTP_AUTHORIZATION,server 不应该将这些头信息传递给 cgi 程序。
  • 重要的数据应该作为 post 请求的消息体,而不是在 uri 中或者 header 中。
  • 对于 TLS 连接的认证,应该在 server 端完成,而不是 cgi 程序来完成。
  • 在一般的 cgi 实现中,cgi 进程作为 server 进程的子进程,用户 server 一样的 usergroup,cgi 程序不应该影响 server 进程,包含:配置文件、文档、日志等。
  • 固定长度缓冲区的使用如果不仔细检查溢出,可能会导致攻击者利用操作系统的“stack smashing”或“stack overflow”漏洞。
  • 要充分考虑 web 请求的无状态性,对于构成一个 web 事务 的多次请求,要充分验证数据的合法性,不能对发起请求的网络代理(user-agent)做任何上下文的假设。

二、fastcgi 规范

官网:www.fastcgi.com
二手中文文档:FastCGI规范

fastcgi 在 cgi 的基础上进行了优化,主要体现在:cgi 程序的执行方式cgi 程序的角色 两方面。

1. 执行方式上的优化
  • 在 cgi 模式中,server 对于每一个请求,都启动一个进程,由这个进程负责 cgi 程序的执行,得到影响后退出进程。即:fork-and-execute
  • 在 fastcgi 模式中:
    • server 和 fastcgi 分开部署,server 和 fastcgi 基于 socket 通信
    • fastcgi 包含 一个负责 socket 通信的父进程若干个负责处理请求的子进程
    • fastcgi 的子进程在处理完一个请求后,并不退出,会等待处理下一个请求
2. 角色上的变化
  • 在 cgi 模式中,server 解析 http 请求,组织 cgi 请求参数,转化为 cgi 请求,由 cgi 程序给出响应,然后再由 server 转化为 http 响应,发送给客户端。即:一个 Responder 角色。
  • 在 fastcgi 模式中,cgi 程序:
    • Responder,像 cgi 模式中一样,作为 响应者 给出响应。
    • Authorizer,根据所收到的 cgi 请求信息,对请求做出一个 认可 或者 未认可 的判定。
    • Filter,对所收到的 http 请求信息进行过滤,返回一个 过滤后的 http 请求信息
3. fastcgi 工作流程
  1. fastcgi 进程启动一个 socket 监听,等待 server 进程的 socket 连接,并启动若干个子进程,用于 cgi 程序的执行。
  2. serverfastcgi 进行 socket 通信,并以 fastcgi 协议的形式,发送 cgi环境变量标准输入数据用于 cgi 执行的子进程
  3. 用于 cgi 执行的子进程 在执行完 cgi 程序后将响应发送给 server 进程。
  4. 用于 cgi 执行的子进程 处理完一个 socket 连接,等待下一个连接。

三、 cgi 个人理解

综上对 rfc3875 的阅读整理以及对 fastcgi 的学习,个人对 cgi 的理解是:

  1. cgi 是一个协议规范,它在职责、实现要求、通信方式、安全性等方面对 server 和 cgi 程序进行了规范,使得很多语言在满足 CGI 规范的前提下,能和 server 分工合作,构建起了我们的动态网站(Dynamic website)。
  2. cgi 规范中缺少 server 对 cgi-script 执行方式的规范,使得 cgi 的执行停留在 fork-and-execute 阶段,性能低下。
  3. fastcgi 在 cgi 程序的执行方式上进行了优化,以 serverfastcgi 进行 socket 通信的方式实现了分开部署,甚至多机器部署。
  4. fastcgi 还进一步扩充了 cgi 程序的 角色,使得 cgi 程序在单一的 Responder 的基础上,有了 AuthorizerFilter 两个功能。
  5. php-cgifastcgi 的一个 php 版本实现,使得 php 可以作为 cgi 语言的一种,承担动态网站的开发。
  6. php-fpmFastCGI Process Manager,它是 php-cgi 的一个进程管理器,提供了对 php-cgi 进程的一系列管理功能,如:平滑终止、平滑重启(加载新的php.ini)等。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容