0

0

探秘基于PHP-FPM进程池

coldplay.xixi

coldplay.xixi

发布时间:2020-08-08 16:42:14

|

2838人浏览过

|

来源于jb51

转载

探秘基于PHP-FPM进程池

PHP 支持多进程而不支持多线程;PHP-FPM 在进程池中运行多个子进程并发处理所有连接请求。通过 ps 查看PHP-FPM进程池(pm.start_servers = 2)状态如下:

root@d856fd02d2fe:~# ps aux -L
USER  PID LWP %CPU NLWP %MEM VSZ RSS TTY  STAT START TIME COMMAND
root   1  1 0.0 1 0.0 4504 692 ?  Ss 13:10 0:00 /bin/sh /usr/local/php/bin/php-fpm start
root   7  7 0.0 1 0.4 176076 19304 ?  Ss 13:10 0:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)
www-data  8  8 0.0 1 0.2 176076 8132 ?  S 13:10 0:00 php-fpm: pool www
www-data  9  9 0.0 1 0.2 176076 8132 ?  S 13:10 0:00 php-fpm: pool www
root  10 10 0.0 1 0.0 18376 3476 ?  Ss 14:11 0:00 bash
root  66 66 0.0 1 0.0 34420 2920 ?  R+ 15:13 0:00 ps aux -L
相关学习推荐:php编程(视频)

从列表中可以看出,进程池www中有两个尚处于空闲状态的子进程PID 8和 PID 9。注:NLWP指轻量级进程数量,即线程数量。

PHP-FPM(FastCGI Process Manager)是什么?PHP-FPM为PHP-CGI提供进程管理方式,可以有效控制内存和进程,可以平滑重载PHP配置,其master process是常驻内存的。FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中更长时间,不是fork-and-execute,并因此获得较高的性能。FastCGI支持分布式部署,可以部署在WEB服务器以外的多个主机上。

探秘手段:模拟多线程并发执行

立即学习PHP免费学习笔记(深入)”;

1. 什么是线程:线程有时又称轻量级进程(Lightweight Process,LWP),通常由线程ID、当前指令指针(PC)、寄存器集合和堆栈组成,是进程中的一个实体,是被系统独立调度的基本单位;线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,与同属一个进程的其它线程共享进程所拥有的全部资源。 由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。由于进程是资源拥有者,创建、撤消与切换开销过大,在对称多处理机(SMP)上同时运行多个线程(Threads)才是更合适的选择。线程的实体包括程序、数据和线程控制块(Thread Control Block,TCB),TCB包括以下信息:

(1)线程状态;

(2)当线程不运行时,被保存的现场资源;

(3)一组执行堆栈;

(4)存放每个线程的局部变量主存;

(5)访问同一个进程中的主存和其它资源。

但使用多个进程会使得应用程序在出现进程池内的进程崩溃或被攻击的情况下变得更加健壮。

2. 模拟多线程:

thread = microtime(true);
 }

 /**
  * 通过socket发送一个新的HTTP连接请求到本机,
  * 此时当前模拟线程既是服务端又是模拟客户端
  *
  * 当前(程序)子进程sleep(1)后会延迟1s才继续执行,但其持有的连接是继续有效的,
  * 不能处理新的连接请求,故这种做法会降低进程池处理并发连接请求的能力,
  * 类似延迟处理还有time_nanosleep()、time_sleep_until()、usleep()。
  * 而且sleep(1)这种做法并不安全,nginx依然可能出现如下错误:
  * “epoll_wait() reported that client prematurely closed connection,
  * so upstream connection is closed too while connecting to upstream”
  *
  * @return void
  */
 public function simulate()
 {
  $run = $_GET['run'] ?? 0;
  if ($run++ < 9) {//最多模拟10个线程
   $fp = fsockopen($this->host, $this->port);
   fputs($fp, "GET {$_SERVER['PHP_SELF']}?run={$run}\r\n\r\n");
   sleep(1);//usleep(500)
   fclose($fp);
  }

  $this->log();
 }

 /**
  * 日志记录当前模拟线程运行时间
  *
  * @return void
  */
 private function log()
 {
  $fp = fopen('simulated.thread', 'a');
  fputs($fp, "Log thread {$this->thread} at " . microtime(true) . "(s)\r\n");

  fclose($fp);
 }
}

$thread = new SimulatedThread();
$thread->simulate();
echo "Started to simulate threads...";

探秘汇总:本人通过运行上述脚本后,发现一些可预料但却不是我曾想到的结果

1. PHP-FPM配置项pm.max_children = 5,simulated.thread记录如下:

Log thread 1508054181.4236 at 1508054182.4244(s)
Log thread 1508054181.4248 at 1508054182.4254(s)
Log thread 1508054181.426 at 1508054182.428(s)
Log thread 1508054181.6095 at 1508054182.6104(s)
Log thread 1508054182.4254 at 1508054183.4262(s)
Log thread 1508054183.4272 at 1508054183.4272(s)
Log thread 1508054182.4269 at 1508054183.4275(s)
Log thread 1508054182.4289 at 1508054183.43(s)
Log thread 1508054182.6085 at 1508054183.6091(s)
Log thread 1508054182.611 at 1508054183.6118(s)

最新生成的(模拟)线程登记出现在红色标示条目位置是因为进程池的并发连接处理能力上限为5,因此它只可能出现在第六条以后的位置。

Log thread 1508058075.042 at 1508058076.0428(s)
Log thread 1508058075.0432 at 1508058076.0439(s)
Log thread 1508058075.0443 at 1508058076.045(s)
Log thread 1508058075.6623 at 1508058076.6634(s)
Log thread 1508058076.0447 at 1508058077.0455(s)
Log thread 1508058076.046 at 1508058077.0466(s)
Log thread 1508058077.0465 at 1508058077.0466(s)
Log thread 1508058076.0469 at 1508058077.0474(s)
Log thread 1508058076.6647 at 1508058077.6659(s)
Log thread 1508058076.6664 at 1508058077.6671(s)

有意思的是绿色条目代表的(模拟)线程和红色条目代表的(模拟)线程的登记时间是一样的,说明两个(模拟)线程是并发执行的。

2. PHP-FPM配置项pm.max_children = 10,simulated.thread记录如下:

LibLibAI
LibLibAI

国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达。

下载
Log thread 1508061169.7956 at 1508061170.7963(s)
Log thread 1508061169.7966 at 1508061170.7976(s)
Log thread 1508061169.7978 at 1508061170.7988(s)
Log thread 1508061170.2896 at 1508061171.2901(s)
Log thread 1508061170.7972 at 1508061171.7978(s)
Log thread 1508061171.7984 at 1508061171.7985(s)
Log thread 1508061170.7982 at 1508061171.7986(s)
Log thread 1508061170.7994 at 1508061171.8(s)
Log thread 1508061171.2907 at 1508061172.2912(s)
Log thread 1508061171.2912 at 1508061172.2915(s)

由于服务端并发连接处理能力上限达到10,因此最新生成的(模拟)线程登记可出现在任何位置。

3. 执行usleep(500)延迟,simulated.thread记录如下:

Log thread 1508059270.3195 at 1508059270.3206(s)
Log thread 1508059270.3208 at 1508059270.3219(s)
Log thread 1508059270.322 at 1508059270.323(s)
Log thread 1508059270.323 at 1508059270.324(s)
Log thread 1508059270.3244 at 1508059270.3261(s)
Log thread 1508059270.3256 at 1508059270.3271(s)
Log thread 1508059270.3275 at 1508059270.3286(s)
Log thread 1508059270.3288 at 1508059270.3299(s)
Log thread 1508059270.3299 at 1508059270.331(s)
Log thread 1508059270.3313 at 1508059270.3314(s)

可见日志记录顺序与(模拟)线程生成的顺序一致。usleep延迟的基本单位是微妙(us, 1 s = 1000000 us)。

从以上的记录可以看出:

1)这些(模拟)线程是第一次请求执行脚本后就自动生成的,一个(模拟)线程紧接着创建了另一个(模拟)线程;

2)这些(模拟)线程中有的是在同一个子进程空间中产生并运行的;

3)前后相邻(模拟)线程生成时间间隔很小,几乎是同时产生,或后一个(模拟)线程在前一个(模拟)线程尚未执行结束并退出之前产生;

4)多个(模拟)线程之间可以并发执行。

所以,上述模拟多线程并发的实现是成功的。PHP-FPM进程池中同一个子进程可先后处理多个连接请求,但同一时间只能处理一个连接请求,未处理连接请求将进入队列等待处理。换句话,同一个子进程不具有并发处理连接请求的能力。

PHP-FPM Pool配置:它允许定义多个池,每个池可定义不同的配置项。以下只是列举了我在探秘过程中还关注过的其他部分配置项

1、 listen:The address on which to accept FastCGI requests.它支持TCP Socket和unix socket两种通讯协议。可设置listen = [::]:9000。

2、listen.allowed_clients:List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. 该配置项为逗号分隔的列表,如listen.allowed_clients = 127.0.0.1,172.17.0.5。

3、pm:Choose how the process manager will control the number of child processes. 该配置项设置FPM管理进程池的方式,包括static、dynamic、ondemand三种。

4、pm.max_requests:The number of requests each child process should execute before respawning. This can be useful to work around memory leaks in 3rd party libraries.设置每个子进程处理请求数的上限,对于处理第三方库中的内存泄漏很有用。

5、pm.status_path:The URI to view the FPM status page.

相关学习推荐:编程视频

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

178

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

35

2026.01.28

ao3中文版官网地址大全
ao3中文版官网地址大全

AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

79

2026.01.28

php怎么写接口教程
php怎么写接口教程

本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

2

2026.01.28

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

4

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

8

2026.01.28

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

24

2026.01.27

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

122

2026.01.26

edge浏览器怎样设置主页 edge浏览器自定义设置教程
edge浏览器怎样设置主页 edge浏览器自定义设置教程

在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

72

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 10万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.2万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号