PHP7内核剖析读书笔记2(Fpm)

    • SAPI
      • Fpm
        • FastCGI介绍
        • PHP通过FastCGI对HTTP请求进行处理的简单概述
          • 扩展知识:网络处理模式
        • 基本实现
          • master进程和worker进程的主要工作
          • worker poll
        • Fpm初始化
          • 配置项
      • Fpm总结

承接上篇继续SAPI的部分案例,此篇只记Fpm的笔记

SAPI

Fpm

Fpm(FastCGI Process Manager)是PHP FastCGI运行模式的一个进程管理器,从它的定义可以看出,Fpm的核心功能是进程管理,那么它用来管理什么进程呢?这个问题需要从FastCGI说起。

FastCGI介绍

FastCGI是Web服务器(如Nignx、Apache)和处理程序之间的一种通信协议,它是与HTTP类似的一种应用层通信协议。注意:它只是一种协议。

PHP通过FastCGI对HTTP请求进行处理的简单概述

PHP只是一个脚本解析器,在Cli模式下可比较简单,可以直接把命令传递给PHP来处理,但是要处理HTTP请求就没办法直接处理,PHP实现了FastCGI协议,在通过配合Web服务器实现对HTTP的处理,Web服务器来处理HTTP请求,然后将解析后的结果通过FastCGI协议转发给处理程序,处理程序处理完成后将结果返回给Web服务器,Web服务器在返回给用户。如下图

扩展知识:网络处理模式

PHP实现了FastCGI协议的处理,但是并没有实现具体的网络处理,比较常用的网络处理模型有以下两种。
多进程模式:由一个主进程和多个子进程组成,主进程负责管理子进程,基本的网络事件由各个子进程来处理,Nginx采用的就是这种模型。
多线程模型:与子进程类似,只是它是线程粒度,这种模式通常会由主线程监听、接收请求,然后交由子线程处理,memcached就是这种模式;有的也是采用多进程那种模式——主线程只负责管理子线程不处理网络事件,各个子线程监听、接收、处理请求,memcached使用UDP协议时采用的就是这种模式。
进程和线程的区别:进程拥有独立的地址空间及资源,而线程没有,线程之间共享进程的地址空间及资源,所以在资源管理上多进程模型比较简单,而多线程模型则需要考虑不同线程之间的资源冲突,也就是线程安全。

基本实现

Fpm是一种多进程模型,它由一个master进程和多个worker进程组成。master进程启动时会创建一个socket,但是不会接受、处理请求,而是由fork出的worker子进程完成请求的接收和处理。

master进程和worker进程的主要工作

master进程的主要工作是管理worker进程,负责fork和杀掉worker进程,比如当前请求比较多worker进程处理不过来,master进程会尝试fork新的worker进程进行处理,而当空闲的worker进程比较多时,则会杀掉部分子进程,避免占用、浪费系统资源。
worker进程的主要工作是处理请求,每个worker进程会竞争Accept请求,接收成功后解析FastCGI,然后执行相应的脚本,处理完成后关闭请求,继续等待新的连接,这就是worker进程的生命周期。从worker进程的生命周期可以看到:一个worker进程只能处理一个请求,只有将一个请求处理完成后才会处理下一个请求,也就是说它是阻塞的模型。Fpm的这种模型大大简化了PHP的资源管理,使得在Fpm模式下不需要考虑并发导致的资源冲突。
注意:阻塞的情况可能遇到的坑,如果当前并发请求导致Fpm超出配置的worker子进程数量会导致阻塞,请求变慢,响应不及时。

worker poll

Fpm可以监听多个端口,每个端口都对应一个worker poll,每个pool下对应多个worker进程,这些归属不同pool的worker进程仍有master进程管理。
在php-fpm.conf中通过[pool name]声明一个worker poll,每个poll各自配置监听的地址、进程管理方式、worker进程数等。

[web1]
listen = 127.0.0.1:9000

[web2]
listen = 127.0.0.1:9001

Fpm初始化

配置项
[pool name]       //pool 名称
user = nginx      //Fpm的启动用户
group = nginx      //Fpm的启动分组
listen = 127.0.0.1:9000      // 监听IP及端口

pm = dynamic      // 进程模式,静态模式,动态模式,按需分配
pm.max_children = 5      // 最大worker进程数
pm.start_servers = 2      // 启动时初始化的worker进程数
pm.min_spare_servers = 1      // 最小空闲worker进程数
pm.max_spare_servers = 3      // 最大空闲worker进程数
pm.process_idle_timeout = 10s;      // worker空闲时间
pm.max_requests = 500      // worker处理的最多请求数,超过这个值worker将被kill

Fpm总结

Fpm是PHP FastCGI运行模式的一个进程管理器,有master进程和fork出来的worker进程。master进程来管理worker进程。动态模式中,如果空闲进程小于pm.min_spare_servers(最小空闲worker进程数)则增加空闲进程,如果空闲进程大于pm.max_spare_servers(最大空闲worker进程数)则杀死多余进程,总进程数不超过max_children。Fpm是阻塞性的,便于管理和分配资源,但是如果大并发会导致数据繁忙,返回不及时(阻塞等待),阻塞等待的进程还会受 listen.backlog 影响,等待的请求数超过listen.backlog设置的值后,超出部分的请求直接返回失败;
Web服务器(nginx等)监听80端口(或者其他端口,默认http80端口),把请求处理解析转发到nginx配置文件中指定的FastCGI协议对应的端口中(一般是9000端口),Fpm中的worker进程会监听接收指定端口的数据进行处理,处理完成后返回给nginx结果,nginx再反馈给请求方。

本文地址:https://blog.csdn.net/qq_15915293/article/details/107875139