PHP的运行模式

344 阅读4分钟

PHP 有几种常见的运行模式,分别是:CLI、CGI、FAST CGI、APACHE2 HANDLER、APACHE DLL模块、ISAPI。有何区别呢?(APACHE、ISAPI不再详解,目前主流为 LNMP)

1、CLI

即命令行运行,这个比较常见,一般用于执行一些脚本,见截图:


php test.php 后面是可以跟参数的,在代码里用 $argv 来接收。

2、CGI

即公共网关接口(Common Gateway Interface),是存放在服务器上,使 HTTP 服务器与其它机器上的程序进行  交谈 的一种工具 。CGI 应用程序不仅能与浏览器进行交互,还可通过数据API 与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。

CGI 的跨平台性能极佳,几乎可以在任何操作系统上实现。

CGI 方式在遇到连接请求时先要创建 CGI 的子进程,激活一个 CGI 进程,然后处理请求,处理完后结束这个子进程。这就是 fork-and-execute 模式。所以用 CGI 方式的服务器有多少连接请求就会有多少 CGI 子进程,子进程反复加载是 CGI 性能低下的主要原因。都会当用户请求数量非常多时,会大量挤占系统的资源,如内存、CPU时间等,造成效能低下。

3、FAST CGI

CGI 的方式我们已经了解,当用户请求数量较多,会造成性能问题。FAST CGI 较好的解决了这个问题,FAST CGI 会事先启动起来,作为一个 CGI 的管理服务器预先启动一系列的子进程来等待处理。接受到请求就交由子进程处理,由于不需要在接受到请求后启动 CGI ,会快很多。综合来看 FAST CGI 像是一个常驻型的 CGI 。

1、Web server 启动时载入 FAST CGI 进程管理器,PHP-FPM 是 FAST CGI 的进程管理器。

2、FAST CGI 自身初始化,启动多个 CGI 解释器进程 (可见多个php-cgi) 并等待来自Web server的请求。

3、当请求Web server时,Web server通过socket请求 FAST CGI 进程管理器,进程管理器选择并连接到一个 CGI 解释器,Web server将 CGI 环境变量和标准输入发送到 FAST CGI 子进程的 php-cgi 。

4、子进程处理请求完成后将标准输出和错误从同一连接返回给Web server,当FastCGI子进程结束后请求便结束。FAST CGI 子进程接着等待处理来自FastCGI进程管理器的下一个连接,在CGI 模式中,php-cgi在此便退出。


看上面截图中红色部分一共有 8 个 FPM 的子进程,这个涉及到了 PHP-FPM 的进程管理模式

4、PHP-FPM的进程管理模式

php-fpm的工作模式和nginx类似,都是一个master,多个 worker 模型。每个 worker 都在accept 本 pool 内的监听套接字(linux已不存在惊群现象)。

在 php-fpm.conf 配置文件中,可以修改上面说到的 FPM 子进程数量,不同的运行模式所产生的子进程数也是不同的。

4.1、ondemand

PHP-FPM 启动时,不会给这个 pool 启动任何一个 worker,是按需启动,当有连接过来才会启动(注意是连接的到来,比如只是 telnet 但是未发送数据也是符合的)。

worker 的数量受限于 pm.max_children 配置,同时受限全局配置 process.max。

如果空闲时间超过 pm.process_idle_timeout 大小,则会自动关闭。这个机制可能会关闭所有的worker 。

优点:按流量需求创建,不浪费系统资源(在硬件如此便宜的时代,这个优点略显鸡肋)

缺点:PHP-FPM 是短连接的,所以每次请求都会先建立连接,建立连接的过程必然会触发上图的执行步骤,所以,在大流量的系统上master进程会变得繁忙,占用系统cpu资源,不适合大流量环境的部署。

4.2、static

PHP-FPM 启动采用固定大小数量的 worker ,在运行期间也不会扩容。

如果配置成 static,只需要考虑配置中的 max_children 的数量,数量取决于cpu的个数和应用的响应时间(上面截图就是此类方式,pm.max_children = 8)。

4.3、dynamic

PHP-FPM 启动时,会初始启动一些worker,在运行过程中动态调整worker数量,worker的数量受限于 pm.max_children 配置,同时受限全局配置 process.max。

优点:动态扩容,不浪费系统资源,master 进程设置的1秒定时器对系统的影响忽略不计。

缺点:如果所有 worker 都在工作,新的请求到来只能等待 master 在1秒定时器内再新建一个worker,这时可能最长等待1s。