zoukankan      html  css  js  c++  java
  • PHP CGI 进化路线

    CGI的进化路线是这样的:CGI->PHPCGI->FastCGI->php-fpm

    官方给出php-fpm替换FastCGI的原因:

    • 支持平滑停止/启动的高级进程管理功能;
    • 可以工作于不同的 uid/gid/chroot 环境下,并监听不同的端口和使用不同的 php.ini 配置文件(可取代 safe_mode 的设置);
    • stdout 和 stderr 日志记录;
    • 在发生意外情况的时候能够重新启动并缓存被破坏的 opcode;
    • 文件上传优化支持;
    • "慢日志" - 记录脚本(不仅记录文件名,还记录 PHP backtrace 信息,可以使用 ptrace或者类似工具读取和分析远程进程的运行数据)运行所导致的异常缓慢;
    • fastcgi_finish_request() - 特殊功能:用于在请求完成和刷新数据后,继续在后台执行耗时的工作(录入视频转换、统计处理等);
    • 动态/静态子进程产生;
    • 基本 SAPI 运行状态信息(类似Apache的 mod_status);
    • 基于 php.ini 的配置文件。

    从官方手册来看,php-fpm是一个FastCGI的进程管理器,用来管理FastCGI进程的。

    CGI

    CGI (Common Gateway Interface)是 Web Server 与后台语言交互的协议,有了这个协议,开发者可以使用任何语言处理 Web Server 发来的请求,动态的生成内容。保证了传递过来的数据是标准格式的(规定了以什么样的格式传哪些数据(URL、查询字符串、POST数据、HTTP header等等)),方便了开发者。

    PHP-CGI

    PHP语言对应与服务器交互的CGI程序就是PHP-CGI。
    CGI程序本身只能解析请求、返回结果,不会进程管理,所以有一个致命的缺点,那就是每处理一个请求都需要fork一个全新的进程,随着Web的兴起,高并发越来越成为常态,这样低效的方式明显不能满足需求(每一次web请求都会有启动和退出进程,也就是最为人诟病的fork-and-execute模式,这样一在大规模并发下,就死翘翘了)。就这样,FastCGI诞生了,CGI程序很快就退出了历史的舞台。

    FastCGI

    它允许在一个进程内处理多个请求,而不是一个请求处理完毕就直接结束进程,性能上有了很大的提高。FastCGI也可以说是一种协议。那么FastCGI是怎么做的呢?

    首先,FastCGI会先启一个master进程,解析配置文件,初始化执行环境,然后再启动多个worker进程。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。
    这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着。当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是FastCGI的对进程的管理。

    web服务器fast-cgi进程管理器初始化->预先fork n个进程
    用户请求->web服务器接收请求->交给fast-cgi进程管理器->fast-cgi进程管理区接收,给其中一个空闲fast-cgi进程处理->处理完成,fast-cgi进程变为空闲状态,等待下次请求->web服务器接收内容->返回给用户

    PHP-FPM

    FPM 是一个 PHP 进程管理器,包含 master 进程和 worker 进程两种进程:master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个 (具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方,下面是我本机上FPM的进程情况:1个master进程,2个worker进程。

    • 从FPM接收到请求,到处理完毕,其具体的流程如下:

    1.FPM的master进程接收到请求。
    2.master进程根据配置指派特定的worker进程进行请求处理,如果没有可用进程,返回错误,这也是我们配合Nginx遇到502错误比较多的原因。
    3.worker进程处理请求,如果超时,返回504错误。
    4.请求处理结束,返回结果。

    php-fpm启动->生成n个fast-cgi协议处理进程->监听一个端口等待任务
    用户请求->web服务器接收请求->请求转发给php-fpm->php-fpm交给一个空闲进程处理
    ->进程处理完成->php-fpm返回给web服务器->web服务器接收数据->返回给用户

    FPM从接收到处理请求的流程就是这样了,那么Nginx又是如何发送请求给FPM的呢?

    Nginx

    Nginx 不仅仅是一个 Web 服务器,也是一个功能强大的 proxy 服务器,除了进行 http 请求的代理,也可以进行许多其他协议请求的代理,包括本文与 fpm 相关的 fastcgi 协议。为了能够使 Nginx 理解 fastcgi 协议,Nginx 提供了 fastcgi 模块来将 http 请求映射为对应的 fastcgi 请求。

    Nginx的FastCGI模块提供了fastcgi_param指令来主要处理这些映射关系,下面 是Nginx的一个配置文件实例,其主要完成的工作是将Nginx中的变量翻译成PHP中能够理解的变量。

    除此之外,非常重要的就是fastcgi_pass指令了,这个指令用于指定FPM进程监听的地址,Nginx会把所有的PHP请求翻译成FastCGI请求之后再发送到这个地址。下面一个简单的可以工作的Nginx配置文件:

    nginx上建立一个虚拟主机,监听80端口,通过location指令将所有以php结尾的请求都交给FastCGI模块处理,从而把所有PHP请求都叫哥了FPM处理,完成Nginx到FPM的闭环

    www.example.com
            |
            |
          Nginx
            |
            |
    路由到www.example.com/index.php
            |
            |
    加载nginx的fast-cgi模块
            |
            |
    fast-cgi监听127.0.0.1:9000地址
            |
            |
    www.example.com/index.php请求到达127.0.0.1:9000
            |
            |
    php-fpm 监听127.0.0.1:9000
            |
            |
    php-fpm 接收到请求,启用worker进程处理请求
            |
            |
    php-fpm 处理完请求,返回给nginx
            |
            |
    nginx将结果通过http返回给浏览器
    

    参考:
    Nginx+Php-fpm运行原理详解
    理解 Nginx 与 PHP-FPM 通信的工作机制
    CGI、FastCGI和PHP-FPM关系图解

  • 相关阅读:
    面向对象(OOP:Objdec Oriented Programming)
    vue中v-model和v-bind区别
    DateTimeFormat
    html中frameset简介
    学习及资料地址
    mybatis+oracle批量新增带序列List对象
    Io流读取并输出文件(例如.mp3格式文件)
    Java从服务器下载图片保存到本地
    转:Java DecimalFormat的主要功能及使用方法
    数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
  • 原文地址:https://www.cnblogs.com/buro79xxd/p/12545336.html
Copyright © 2011-2022 走看看