Fastcgi协议分析

Fastcgi Record

Fastcgi协议服务器中间件和某个后端语言之间进行数据交换的协议

其由多个Record组成,record有header和body,服务器中间件将这两个按照fastcgi协议的规则进行封装好发送给后端语言,后端语言解码之后,获得具体的数据,并执行对应的操作之后,将结果通过fastcgi协议的规则返回给服务器中间件。

其header固定为8个字节,body是有其头中的contentLength指定,结构:

typedef struct {
  /* Header 消息头信息 */
  unsigned char version; // 用于表示 FastCGI 协议版本号
  unsigned char type; // 用于标识 FastCGI 消息的类型, 即用于指定处理这个消息的方法
  unsigned char requestIdB1; // 用ID值标识出当前所属的 FastCGI 请求
  unsigned char requestIdB0;
  unsigned char contentLengthB1; // 数据包包体Body所占字节数
  unsigned char contentLengthB0;
  unsigned char paddingLength; // 额外块大小
  unsigned char reserved; 

  /* Body 消息主体 */
  unsigned char contentData[contentLength];
  unsigned char paddingData[paddingLength];
} FCGI_Record;

后端语言解析了fastcgi之后得到其中的contentLength对应的值,之后再在请求的TCP流中读取对应大小为contentLength的长度,这个就是body中的数据

type解析

type就是一个Record的作用,因为我一个TCP流中传输了多种record,指向同一个requestId来同时执行不同的作用

主要的type作用

type值 其作用
1 在与php-fpm建立连接之后发送的第一个消息就中是1,表明此消息为请求开始的第一个消息
2 异常断开与php-fpm的交互
3 在与php-fpm交互中所发的最后一个消息中type值为此,以表明交互的正常结束
4 在交互过程中给php-fpm传递环境变量时,将type设为此,以表明消息中包含的数据为某个name-value对
5 Web服务器将从浏览器接收到的POST请求数据(表单提交等)以消息的形式发给php-fpm,这种消息的type就得设为5
6 php-fpm给Web服务器回的正常响应消息的type就设为6
7 php-fpm给Web服务器回的错误响应设为7

其中当后端语言接收到对应type对应的值是4的时候,就会将对应的body中的内容通过解析成键值对的形式,就是环境变量。

PHP-FPM

fastcgi进程管理器用于替换PHP FastCGI的大部分附加功能,对于高负载的网站是很有用的。

其默认监听端口 9000

包含了master worker进程,master进程负责与web服务器中间件进行通信,接收服务器中间按照 FastCGI 的规则打包好的用户请求,再将请求转发给 worker 进程进行处理。worker进程负责后端动态执行PHP代码