1.3.4 请求处理
最后更新于:2022-04-02 05:16:21
### 1.3.4 请求处理
`fpm_run()`执行后将fork出worker进程,worker进程返回`main()`中继续向下执行,后面的流程就是worker进程不断accept请求,然后执行PHP脚本并返回。整体流程如下:
* __(1)等待请求:__ worker进程阻塞在fcgi_accept_request()等待请求;
* __(2)解析请求:__ fastcgi请求到达后被worker接收,然后开始接收并解析请求数据,直到request数据完全到达;
* __(3)请求初始化:__ 执行php_request_startup(),此阶段会调用每个扩展的:PHP_RINIT_FUNCTION();
* __(4)编译、执行:__ 由php_execute_script()完成PHP脚本的编译、执行;
* __(5)关闭请求:__ 请求完成后执行php_request_shutdown(),此阶段会调用每个扩展的:PHP_RSHUTDOWN_FUNCTION(),然后进入步骤(1)等待下一个请求。
```c
int main(int argc, char *argv[])
{
...
fcgi_fd = fpm_run(&max_requests);
parent = 0;
//初始化fastcgi请求
request = fpm_init_request(fcgi_fd);
//worker进程将阻塞在这,等待请求
while (EXPECTED(fcgi_accept_request(request) >= 0)) {
SG(server_context) = (void *) request;
init_request_info();
//请求开始
if (UNEXPECTED(php_request_startup() == FAILURE)) {
...
}
...
fpm_request_executing();
//编译、执行PHP脚本
php_execute_script(&file_handle);
...
//请求结束
php_request_shutdown((void *) 0);
...
}
...
//worker进程退出
php_module_shutdown();
...
}
```
worker进程一次请求的处理被划分为5个阶段:
* __FPM_REQUEST_ACCEPTING:__ 等待请求阶段
* __FPM_REQUEST_READING_HEADERS:__ 读取fastcgi请求header阶段
* __FPM_REQUEST_INFO:__ 获取请求信息阶段,此阶段是将请求的method、query stirng、request uri等信息保存到各worker进程的fpm_scoreboard_proc_s结构中,此操作需要加锁,因为master进程也会操作此结构
* __FPM_REQUEST_EXECUTING:__ 执行请求阶段
* __FPM_REQUEST_END:__ 没有使用
* __FPM_REQUEST_FINISHED:__ 请求处理完成
worker处理到各个阶段时将会把当前阶段更新到`fpm_scoreboard_proc_s->request_stage`,master进程正是通过这个标识判断worker进程是否空闲的。
';