最新公告
  • 欢迎您访问爱上源码网,分享精品整站源码,网站模板,游戏源码,APP小程序源码以及视频教程免费下载;服务永无止境!立即加入我们
  • 基于PHP-FPM进程池的探索

    爱上源码网文章基于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

    从列表中可以看出,进程池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. 模拟多线程:

    <?php
    /**
     * PHP 只支持多进程不支持多线程。
     *
     * PHP-FPM 在进程池中运行多个子进程并发处理所有连接,
     * 同一个子进程可先后处理多个连接请求,但同一时间
     * 只能处理一个连接请求,未处理连接请求将进入队列等待处理
     *
     */
    
    class SimulatedThread
    {
     //模拟线程
     private $thread;
    
     //主机名
     private $host = 'tcp://172.17.0.5';
    
     //端口号
     private $port = 80;
    
     public function __construct()
     {
      //采用当前时间给线程编号
      $this->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记录如下:

    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-FPM进程池的探索的详细内容,更多请关注爱上源码网其它相关文章!

  • 微信
  • 分享
  • 相关标签:php-fpm 进程池
  • 本文转载于:jb51,如有侵犯,请联系916990011@qq.com删除
    • 上一篇:分享几种PHP并发场景的解决方案
    • 下一篇:PHP如何使用Redis?(常见使用场景介绍)

    相关文章

    相关视频

    • 详解PHP7中php.ini、php-fpm和ww…
    • laravel安装和php-fpm、nginx配置…
    • php-fpm.conf配置项有哪些
    • 详解PHP中PHP-FPM是什么?有什么用?
    • 基于PHP-FPM进程池的探索
    • php-fpm优化
    • PHP-FPM参数优化
    • ThinkPHP6.0 杂项

    本文有爱上源码下载完入驻作者发布,如果对您版权造成侵害,可以联系本站站长管理进行维权删除,本站收到维权24小时内进行处理,谢谢您关注23ym.cn!
    本站分享大量程序员技术文章以及对编程开发的初级入门教程,包括图文讲解笔记和高清视频下载~

    重要声明:
    1.本站视频教程,软件及网站源码版权均属于原作者所有,您必须在下载后的24个小时之内,从您的电脑中删除!非法商业用途,后果自负!
    2.本站不保证所提供下载资源的安全性和完整性,仅供下载学习之用!如链接失效或资源含外站广告,请联系客服处理!给予奖励!
    3.本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!本站提供有偿服务!如有侵权请联系在线客服!
    4.如您手中有优质资源或教程,可以自助投稿发布,成功分享后有奖励和额外收入!
    5.如您需要正版微擎模块可联系本站客服,我们有价值30w+商业微擎应用出售微擎坑位和招收代理!
    6.400电话/软著/ICP,EDI许可证/商标特价办理中!
    爱上源码下载网 » 基于PHP-FPM进程池的探索

    常见问题FAQ

    从网站下载的源码都有安装教程么?不会安装怎么办?
    本站发布的网站源码和模板资源大部分在压缩包内都有教程,如您不会安装可以联系本站在线技术进行付费安装。
    爱上源码的所有源码都是亲测能正常运行的么?
    本站目前拥有资源10w+,包含整站源码,网站模板,游戏源码,小程序源码,视频教程,破解软件等,每天也在测试更新;因时间和精力有限我们无法对资源进行一一测试,只能保证所分享资源内容无误,希望理解。
    我手中的优质资源可以在你这换钱或者VIP么?
    爱上源码支持投稿,欢迎发布您手中的优质资源进行售卖;本站VIP支持免费获取,目前邀请10人注册爱上源码即可免费获取VIP。
    爱上源码除了资源分享还有其他业务没?
    【价值30W+微擎模块出售正版商业微擎坑位及招收代理,详情咨询本站客服!】我们团队目前运营并推广几套商业化saas智能小程序系统能满足大部分小程序开发需求,并由SaaS和独立部署版商城小程序系统;另外销售400电话,各种ICP/EDI资质证书办理,软著和商标注册服务等。

    发表评论

    • 19会员总数(位)
    • 33905资源总数(个)
    • 0本周发布(个)
    • 0 今日发布(个)
    • 301稳定运行(天)

    提供最优质的资源集合

    开通VIP 源码下载