PHP内核剖析 Fpm之worker请求处理

    以PHP7为学习基础,PHP7的源码为C编写的。

    参考书籍:《PHP内核剖析》秦鹏/著

           GitHub网页:https://github.com/pangudashu/php7-internal/blob/master/1/fpm.md

正文:

    worker进程,即PHP Fpm采用多线程模式下,进行服务请求处理的子进程。

    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)等待下一个请求。

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进程是否空闲的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章