文章内容更新请以 WGrape GitHub博客 : HTTP服务器原理之CGI协议 为准
前言
本文原创,著作权归WGrape所有,未经授权,严禁转载
预备
- HTTP服务器 又称 Web服务器,是最常用的协议服务器之一。
- 常见的协议服务器主要有 : HTTP协议服务器、TCP协议/UDP协议服务器、Websocket协议服务器、FTP协议服务器
- CGI 是HTTP服务器独有的协议,只有HTTP服务器需要遵循 CGI 协议,其他的TCP等协议服务器则没有CGI之类的协议。
- CGI 程序是最难让人理解的一个东西,其不是表示一个具体的东西,而是一个概念,表示专门用于处理请求的处理程序。即 CGI 程序 本质上就只是一个 处理程序 ,专门用于处理请求。
- 因为 CGI 协议中所定义规范的 CGI程序 就只是一个处理请求的程序而已,可能 CGI协议 本身都没想好 CGI 程序中到底需要有什么语言级别的解析模块。
- 因此我们不用管 CGI 程序 到底是什么语言编写 ,CGI 程序 到底是由什么组成 ,其内部都包含什么解析编译等语言引擎级别的东西。因为 CGI 协议中所定义规范的 CGI程序 就只是一个处理请求的程序而已
CGI RFC
对 CGI 的几乎一切疑问,通过阅读 CGI 的 RFC 都即可解决。CGI RFC 地址
原理
CGI 协议
- 在左边实现 CGI 协议 的程序叫做 :Server 服务器
- 在右边实现 CGI 协议 的程序叫做 :CGI 程序,或者就简单的把它理解为 处理请求的 处理程序
- Script 等同于 CGI程序,都是 CGI协议 规定的 处理程序,二者是一个概念。
- CGI 程序并不是某个具体的东西,而是一个概念,一个表示 用来处理请求 的 处理程序 模型
- 在 Server 中通过 注入 Module 模块 的方法,实现了服务器与处理程序的解耦
CGI 协议实现
- CGI 协议规定了 CGI程序(处理程序) 在收到请求时,通过 fork-and-execute 来实现对不同请求的处理,这也正是 CGI 协议的缺点 :在并发时会严重消耗资源甚至崩溃
- 每一个 PHP-CGI 程序都只是一个 CGI 程序,前缀 PHP 只是表示 其为用 PHP 编写的 处理程序 。
FastCGI 协议
为了弥补 CGI 协议的不足,FastCGI协议应运而生,其大体与 CGI 协议的结构图一样,主要不同的是:FastCGI协议 要求 处理程序使用 Master-worker 模式,不再推荐使用 fork-and-execute 模式。
- FPM 即 FastCGI Process Manager
- 前面说了 CGI 程序是处理程序,那么 FPM 就是 处理程序的 管理程序 。FPM 就是专门用于管理 CGI 的一个程序
- 同 CGI 程序一样 ,FPM 程序 也只是一个概念,一个模型而已 :用于描述 管理处理程序 的程序
FastCGI 协议实现
- PHP-FPM 前缀 PHP 同样也只是表示 用 PHP 实现的 FPM 。
- PHP-FPM 会在第一次启动的时候,启动一个 master 主进程,并维护 worker 进程池,每一个worker进程都是用于处理请求的 CGI 程序 (处理程序)
Nginx配置PHP FastCGI
配置Nginx的时候能发现总是需要配置一个upstream的东西,它就是PHP的一个fastCGI程序,它会和Nginx通信。Nginx把请求到的信息,转发调用起PHP fatcgi程序,这样调接口的时候 ,就运行起了一个PHP请求进程、
upstream vault {
server 127.0.0.1:8001;
}
server {
listen 80;
server_name vault.shopshop.space;
error_log /var/log/nginx/vault.shopshop.space_error.log;
access_log /var/log/nginx/vault.shopshop.space_access.log;
root /path/to/public;
index index.php;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass vault;
}
}