前言

偶然之间想了解下,php-fpm 请求达到max_children最大值后,新进入的请求怎么办?是抛出502还是等待前面的请求完成后,再将请求交给处理完毕的进程处理呢。

准备工作

运行环境:LNMP
php 版本:php8.1+

首先要先了解nginx 和 php-fpm 的交互模式采用的是惊群现象。网上很多说是nginx-work将请求交给了php-fpm主进程,再由php-fpm主进程将请求下发给下面的子进程。 这其实是错误的,不信的话,你可以将主进程删掉,然后请求试试,看能不能正常处理。

如下图所示,我把master主进程干掉后,nginx-work 转发依然可以得到php正确的处理,所以可得结论:nginx-work并不是把请求交给了master主进程处理请求。而是采用惊群现象,多个php-fpm子进程抢占式处理请求,当一个进程拿到此请求的锁后,其它进程则不能再处理此请求。

在这里插入图片描述

回归正题
如下图所示,我干掉了绝大部分php进程(master进程,php-fpm 子进程),只留下了一个php-fpm 进程。

在这里插入图片描述
然后我建立了两个请求

request - 1 : 等待10s

public function test()
{
    sleep(10);
}

reques-2 :立即通过id登录

public function idLogin(int $id)
{
     $userEntity = $this->userService->getUserIdEntity($id);
     if(empty($userEntity))
     {
         throw new UserException(__('user.userNotFound'));
     }     $token = $this->userService->userLogin($userEntity);     return [
         'token' =>  $token,
         'user'  =>  $userEntity
     ];
 }

执行顺序
先执行1 , 让唯一的一个php工作进程被占用。
再执行2,此时的情况是。请求一直在被堵塞,待请求1的10s解除后,请求2理解正确返回了结果。

总结

右上测试可知:php - fpm 请求达到max_children最大值后,新进入的请求会被阻塞(可以理解为被放置在了某个队列中),待前面的请求处理完毕后,一个一个交付给空闲进程处理。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部