LAMP/LNMP服务器搭建:图文解析相关概念关系

本文目录结构预览:

LAMP/LNMP服务器搭建:图文解析相关概念关系

一、简介

搭建 LAMP/LNMP 服务器时,常常会碰到 CGI、FastCGI 以及 PHP-FPM 等几个相关概念。倘若对这些概念了解得不够深入,就很难搭建出高性能的服务器。本文将以图文的方式,对这些概念之间的关系进行解释。

在这之前,先了解一下相关的概念。

二、相关概念

1、Web 服务器

Web 服务器的作用是处理 html 等静态资源,以便客户能够通过浏览器来进行访问。主流的 Web 服务器包含 Apache、IIS、Nginx、Lighttpd 等。

2、SAPI

SAPI 是服务器应用程序编程接口,它是一个 PHP 与其他应用进行交互的接口。PHP 脚本有很多种执行方式,其一可以通过 Web 服务器来执行,其二可以直接在命令行下执行,其三还可以嵌入在其他程序中。SAPI 在这儿所起到的作用,是提供了一个能与外部应用(例如 Nginx 服务器)进行通信的接口,这样一来,PHP 就能够和其他应用进行数据交互。

PHP 本身可被理解为是一个能提供语言编译与执行服务的库函数,它具备标准的输入和输出。SAPI 是 PHP 的接入层,它会接收用户的请求,接着调用 PHP 内核所提供的一些接口来完成 PHP 脚本的执行。因此,从严格意义上来说,SAPI 并不能算作 PHP 内核的一部分。

PHP 常用的 SAPI 包含 CGI、FastCGI、apache2handler、CLI 等。CLI 可在命令行下执行 PHP 脚本,它是单进程的,其处理模型较为简单。而 CGI 和 FastCGI 相对更为复杂,它们实现了网络处理模块,以便与 web 服务器进行交互。

查看 PHP 源码的/sapi 目录,能够方便地查看到当前 PHP 版本所支持的 SAPI 有哪些。例如:

在[d:\Downloads\php-8.1.2\sapi]路径下执行 list 操作。
- 可以在这个目录中找到与不同服务器环境适配的 sapi 实现。
Name 相关信息,Host 相关信息,Protocol 相关信息,User Name 相关信息。
请提供需要改写的句子呀,你没有给出具体的内容呢。
apache2handler/
cgi/
cli/
embed/
fpm/
fuzzer/
litespeed/
phpdbg/

3、Zend

Zend 是 PHP 语言中极为重要的部分,同时也是 PHP 最基础、最核心的部分,其源码位于 /Zend 目录下。PHP 代码从开始编译到最终执行,整个过程都是由 Zend 来完成的。Zend 整体是由两个部分构成的:

三、工作原理

1、静态请求

早期的 Web 服务会按照客户端的请求,把保存在 Web 服务器硬盘里的数据转发过去。在这种情况下,客户端每次获取的信息都是相同的内容,像图片、css 文件、HTML 文件等这些都是静态请求。

2、CGI 模式

通常客户端的请求会被 Web 服务器截获。若为静态请求,Web 服务器(例如:nginx)会自行进行处理。要是为动态请求,就会抛给后端应用服务器(例如:php-cgi)去处理。所以,在 web 服务器与应用服务器之间如何进行通信成为了主要的问题,而这正是 SAPI 的作用。CGI 是 SAPI 规范中的一种,php-cgi 是 CGI 的具体实现。

CGI 即通用网关接口规范。此规范详细地阐述了在获取及返回数据的过程中,Web 服务器(例如:nginx)与后端应用服务器(例如:php-cgi)传输数据的标准。(就如同 Web 浏览器与 Web 服务器进行数据交换所遵循的协议是 HTTP 协议一样)

也就是说,CGI 就是专门用来和 Web 服务器打交道的。Web 服务器一旦收到用户的请求,就会把该请求提交给 CGI 程序,比如 php-cgi。CGI 程序会依据请求提交的参数进行相应的处理,也就是对 php 进行解析。接着,CGI 程序会输出标准的 HTML 资源,之后将其返回给 Web 服务器。最后,Web 服务器再把这些资源返回给客户端。这便是 CGI 的工作原理。

CGI 程序能够用任何一种语言来编写,只要该语言具备标准输入、输出以及环境变量。CGI 的益处在于它完全独立于任何服务器,仅仅充当中间的角色。比如,它可以给 Nginx 和 php 提供接口。它们通过 CGI 进行连接从而完成数据的传递。这样做的好处是能够最大程度地减少这两个程序之间的关联,让它们变得更加独立。

3、FastCGI 模式

FastCGI 即快速通用网关接口,它是 CGI 的增强版本,是为了提升 CGI 的性能而产生的。

PHP-FPM 是 PHP 的 FastCGI 进程管理器。FastCGI 仅仅是一个协议规范,它需要某个程序来进行具体的实现,而 PHP-FPM 就是那个承担具体实现任务的程序。

在 CGI 模式里,CGI 程序也就是 php-cgi。对于每个 HTTP 请求,它会 fork 出一个新的 php-cgi 进程来进行处理,处理内容包括解析配置文件、初始化执行环境以及处理请求等。接着,把这个进程处理完的结果经由 Web 服务器转发给客户端,之后这个 php-cgi 进程就会退出。如果下次用户请求动态资源,CGI 程序会 fork 一个新的 php-cgi 进程。之后又会再次 fork 新的进程,如此不断循环。我们将这种情况称为 fork-and-execute 模式。在大规模并发的情况下,这种模式会显得很无力。

在 FastCGI 模式里,FastCGI 程序也就是 PHP-FPM 会先进行 fork 操作,生成一个 master 进程,接着对配置文件进行解析,同时初始化执行环境,之后再 fork 出多个 worker 进程。master 进程负责和 Web 服务器进行通信。当接收到 HTTP 请求后,master 进程会把它传递给一个空闲的 worker 进程。接着,master 进程能够立刻继续接受下一个请求。这样就避免了重复的初始化操作,效率自然得以提高。当 worker 进程数量不足时,master 进程能够依据配置预先启动若干个 worker 进程并等待;而当空闲的 worker 进程数量过多时,也会关闭一部分。这样做既提升了性能,又节省了系统资源。worker 进程的主要职责是调用 Zend 虚拟机来编译并执行 PHP 脚本的代码。在完成处理后,它会将处理结果返回给 Web 服务器。这便是 PHP-FPM 的基本工作原理。

在 Linux 环境下查看 PHP-FPM 的进程情况是这样的,其中第一个进程是 master 进程,而后面的那些进程则是 worker 进程。

在 /var/log 目录下,使用 ps aux 命令,然后通过管道将其输出传递给 grep fpm 命令,以查找相关进程信息。
root 进程,其进程号为 960,占用 CPU 比例为 0.0,内存占用比例为 0.2,内存使用量为 196284,虚拟内存大小为 9824,处于系统运行状态,启动时间为 10:52,运行时间为 0:00,该进程是 php-fpm 的主进程,其配置文件为 /etc/php/7.3/fpm/php-fpm.conf
www-data 运行着,其占用资源情况为 961,所占比例为 0.0 ,占用空间为 0.1 ,内存大小为 196284 ,使用的内存为 7504 ,所处位置为问号处,状态为 S ,启动时间为 10:52 ,运行时长为 0:00 ,执行的程序为 php-fpm ,其所属的池为 www
www-data 占用资源情况为 962,其资源使用比例为 0.0,占用空间为 0.1,总空间为 196284,实际使用空间为 7504,所处位置为问号标记处,其状态为 S,开始时间为 10:52,持续时间为 0:00,执行的任务是 php-fpm: pool www
www-data 占用资源情况为 963 ,其资源使用比例为 0.0 ,占用内存为 196284 ,使用的内存量为 7504 ,所处位置为问号处,状态为 S ,开始时间为 10:52 ,运行时长为 0:00 ,对应的是 php-fpm 中的 pool www 。
www-data 进程的相关信息如下:其进程号为 964,CPU 使用率为 0.0,内存使用率为 0.1,占用内存 196284,使用的内存为 7504,所在位置为问号处,状态为 S,启动时间为 10:52,运行时长为 0:00,正在运行 php-fpm:pool www 相关的任务。
www-data 的相关情况如下:其进程 ID 为 965,CPU 使用率为 0.0,内存使用率为 0.1,内存占用大小为 196284,内存使用量为 7508,所处位置为问号处,进程状态为 S,启动时间为 10:52,运行时间为 0:00,执行的是 php-fpm: pool www 这个操作。

详细步骤:

Web 服务器(Nginx)在启动时会载入 FastCGI 进程管理器(PHP-FPM)。FastCGI 进程管理器会进行自身的初始化操作。接着,它会启动多个 CGI 解释器进程(php-cgi)。之后,它会等待来自 Web Server 的连接。

当有 Web 服务器发出请求时,FastCGI 进程管理器会进行选择并与一个 CGI 解释器相连接。接着,Web 服务器会把 CGI 环境变量以及标准输入传递给 FastCGI 子进程 php-cgi。

FastCGI 子进程处理完毕后,会把标准输出和错误信息通过同一连接返还给 Web 服务器。当 FastCGI 子进程关闭连接时,就意味着该请求处理完毕了。(在 CGI 模式里,php-cgi 此时就会退出)

FastCGI 子进程处于等待状态,然后对来自 FastCGI 进程管理器的下一个连接进行处理。

FastCGI 就如同一个长期存在的 CGI 。它能够一直处于运行状态,一旦被激活,就无需每次都花费时间去进行 fork 操作。它还具备支持分布式运算的能力,也就是说 FastCGI 程序可以在网站服务器之外的主机上运行,并且能够接收来自其他网站服务器的请求。

FastCGI 是一种开放扩展。它与语言无关,具有可伸缩架构。其主要行为是把 CGI 进程保持在内存中,凭借此方式能获得较高的性能。大家都知道,CGI 程序反复加载会导致 CGI 性能低下。如果 CGI 进程能一直留在内存中,并且接受 FastCGI 进程管理器的调度,那么就能够提供良好的性能、具备良好的伸缩性以及具备 Fail-Over 特性等。

四、CGI 与 FastCGI 的区别

CGI 模式下,若直接将 php-cgi 进程杀死,那么 php 便无法运行。然而在 FastCGI 模式中,不存在这样的问题,其守护进程能够平稳地重新生成新的 php-cgi 子进程。

对于 CGI 而言,每一个 Web 请求到来时,PHP 都需要重新对 php.ini 进行解析,需要重新载入所有的扩展,并且要重新初始化全部的数据结构。然而,使用 FastCGI 的话,所有这些情况都仅仅在进程启动的时候发生一次。还有一个额外的益处,那就是持续数据库连接是可以正常工作的。

修改 php.ini 之后,php-cgi 进程无法实现平滑重启。php-fpm 的处理机制是,新的 worker 会采用新的配置,而已经存在的 worker 在处理完手头的工作后,就不再接受新的请求,并且会准备退出,通过这样的机制来实现平滑过渡。

因为 FastCGI 是多进程的,所以它比 CGI 会消耗更多的服务器内存。每个 php-cgi 解释器进程会消耗 7MB 至 25MB 的内存,把这个数字分别乘以 50 或者 100 的话,就会得到一个很大的内存数。

为了方便理解,以下是对相关概念的简单介绍:

五、参考

官方:

针对服务器的扩展:

FastCGI 进程管理器(FPM):

PHP 的命令行模式:

php_sapi_name 函数:

程序猿专栏:

Fast CGI 工作原理:

nginx+php-fpm工作原理:

全面了解CGI、FastCGI、PHP-FPM:

避免PHP-FPM内存泄漏导致内存耗尽:

php-fpm的reload过程:

对于php-fpm和cgi,还有并发响应的理解:

深入理解PHP之:Nginx 与 FPM 的工作机制:

其它:

CGI综述:

php 有五大运行模式,分别是 CGI、FAST-CGI、CLI、ISAPI 和 APACHE 模式,下面来浅谈一下这些模式。

SSRF漏洞之FastCGI利用篇:

平滑重启更新(GR机制):

nginx.conf中的fastcgi_pass:

PHP-FPM进程数的设定:

书籍:

《PHP7内核剖析》、《Modern PHP》

你可能想看:
« 上一篇
下一篇 »

相关推荐

php实时推送,php实地培训

2026年10月05日

53阅读

php乱码出现问号的原因,php乱码出现问号的原因有哪些

2026年10月05日

44阅读

php一句话木马,一句话木马ctf

2026年10月05日

48阅读

php获取数组长度,php中如何获取数组的长度

2026年10月05日

50阅读

php面试题库及答案,php程序员面试真题库

2026年10月05日

47阅读

phpcontent-type修改,php源码二次修改需要多少钱

2026年10月05日

42阅读