FPM进程过多,挤爆了CPU,导致短时间内服务器接口迟缓的问题如何解决?

1. 运行环境

LNMP

1). 当前使用的 Laravel 版本?

Laravel 6.20.44

2). 当前使用的 php/php-fpm 版本?

PHP 版本:7.4.30

php-fpm 版本:

3). 当前系统

CentOS 7.9
4核 8G

4). 业务环境

业务环境:生产
负载均衡:无(所有服务均在一个机器上)

5). 相关软件版本

Nginx1.22.1、MySQL5.7.39、Redis 6.2.7

2. 问题描述?

抢购商品的场景,200人左右,逐渐增长中,现在有一个问题就是,到点抢购时,cpu(4核)就被fpm给干满了,业务跑完后(下单的业务已经变成异步队列形式,所有流程上的逻辑没有耗费任何时间)cpu就正常了。大部分是用户占用,内存占用很低;开启了Opcahe、路由缓存、配置文件缓存、能搞的都搞了,php慢日志也没有什么错误。

我用jmeter在测试环境测试了一番(2核4G的),直接请求了单个php文件,200并发时cpu没问题;但是使用laravel框架路由访问到控制器内(只是输出一个字符串,没有任何业务逻辑),这一瞬间也把cpu干爆了(2-3s的样子,生产环境用户点击更复杂大概10s左右用户不同时刷新了cpu也就立马下来了)
Laravel

3. 您期望得到的结果?

希望有经验的大神能客观指点一下如下疑问:
1、你们并发访问laravel框架内控制器的方法时fpm占用cpu资源率是多少,会不会爆满?
2、是否有必要使用swoole?
3、如需要提升配置,是升单个服务器的配置还是使用多个服务器做负载均衡?

4. 您实际得到的结果?

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 58

抢购场景200人不一定只有200并发,如果前端不控制点击和刷新频率的话,这点人直接拉高配置就好,前端控制,oss这些做好,还用不上负载均衡。

1年前 评论
ononl (作者) 1年前
jingyu_wjy (楼主) 1年前
jingyu_wjy (楼主) 1年前
白小二 1年前
if (!in_array(rand(100, 200) % 11, [1, 3, 5, 7, 9])) {
            return $this->error("你被挤出队伍了");
        }

试试这个

1年前 评论
jingyu_wjy (楼主) 1年前
Sw-A (作者) 1年前
我爱大可乐 1年前
Sw-A (作者) 1年前
raybon 1年前
Sw-A (作者) 1年前
我爱大可乐 1年前

fpm 的 pm 设置为 staticpm.max_children 设置为CPU核心的两倍。然后如果还是扛不住,建议考虑做弹性伸缩支持,因为你这个其实就是临时性的需求。完全可以通过临时申请服务器来解决问题。

其实PHP 还支持 opcache, DB 持久链接,preload预加载,我觉得你都可以参考下。

1年前 评论
mowangjuanzi (作者) 1年前
jingyu_wjy (楼主) 1年前
九霄道长 1年前
jingyu_wjy (楼主) 1年前
jingyu_wjy (楼主) 1年前
mowangjuanzi (作者) 1年前
jingyu_wjy (楼主) 1年前
mowangjuanzi (作者) 1年前

php的优化有限。无所谓是代码层fpm层。除去这两个之外的任何手段,都没用,想都不用想。

  • fpm层
    • pm 模式
    • 进程数量
    • opcache (8.x支持jit可以试试)
  • 代码层
    • 优化逻辑
    • 减少不必要的网络开销
    • 提前返回

说说swoole
因为laravel的特性,使用swoole,只能每个请求都重新初始化所有的全局对象container、request、response、validate、db等。swoole和opcache的结合没研究过不知道opcache能不能助力swoole,如果不能那每次光文件I/O开销就够一壶了。如果用swoole还是建议使用hyperf等框架

世界加钱可及
在所有的优化手段都应用后还是慢,可以考虑加机器了。一台不够两台,两台不够10台。相信在10台机器都不够的前提下,你一定是不缺钱的。

1年前 评论
raybon 1年前

200 并发 4核8G 应该是扛不住的,你可以试试修改 php-fpm.conf 改成 static,但不一定管用,如果是到点抢购,可以用云平台的弹性伸缩+负载均衡,直接镜像你原来的服务器,操作起来很简单,就注意点如果数据库和 redis 在原服务器存储,弹性服务器一定要写成主服务器的 ip。

  1. 可以把并发接口单独部署在 laravels 博客:记使用 Laravel-s 抵御百度爬虫的经历
  2. 是否提升服务器的配置,在于平时情况避免浪费
1年前 评论
jingyu_wjy (楼主) 1年前

在 Laravel 框架中,当多个请求同时访问控制器的方法时,FPM(FastCGI Process Manager)的 CPU 资源占用率会根据请求的复杂度和数量以及服务器的配置情况而异。因此,无法确定 FPM 在并发访问时的 CPU 资源占用率会是多少,也不能保证它不会爆满。通常情况下,为了避免 FPM 占用过多 CPU 资源,应该尽量减少对控制器方法的并发访问,或者通过优化服务器配置来提高 FPM 的处理能力。

1年前 评论
raybon 1年前

换webman吧

1年前 评论
jingyu_wjy (楼主) 1年前
抄你码科技有限公司

升到php8+lv9+octane(swoole),你的单机还可以继续战斗。。

有没有可能。。你的瓶颈是mysql。。不是php

1年前 评论
╰ゝSakura 1年前
抄你码科技有限公司 (作者) 1年前
jingyu_wjy (楼主) 1年前
jingyu_wjy (楼主) 1年前
╰ゝSakura 1年前
╰ゝSakura

从你的问题来看的话,目前感觉就是php-fpm过多,CPU占用率高,但是包括其他指标都没有提供,有点难看出瓶颈 首先建议,先把php-fpm进程改成static,数量一般都是64左右,开opcache,再重新压测下看看吧

1年前 评论
jingyu_wjy (楼主) 1年前
╰ゝSakura (作者) 1年前

可以尝试一下升级 php8.1, 开启Jit,个人并发自测过,有倍数级的并发提升。

1年前 评论
jingyu_wjy (楼主) 1年前
  1. 生产环境建议把redis mysql独立出去 一般情况都是买的rds
  2. php-fpm环境调优无非就是: 框架本身的缓存(配置、路由、自动加载),fpm、opcache配置这一块的还是很重要,可以看下相关资料
  3. 看评论区有的朋友提到swoole,重构代价很大,不过可以将部分业务独立出去 用swoole来做,我司早上某个时间点高峰期(同时1000左右吧)某个模块也是采用swoole来做的api,稳定运行几年了 整个项目架构: 能异步就异步,能分离就分离
1年前 评论
jingyu_wjy (楼主) 1年前

使用Laravel Octane,带宽拉高,我觉得不使用Laravel Octane或swoole,拯救不了,除非堆配置

1年前 评论
jingyu_wjy (楼主) 1年前
xiaochong0302

php 如果是 fpm 模式选框架还是 phalcon 这种扩展性的香,laravel什么优雅纯粹扯犊子

1年前 评论
jingyu_wjy (楼主) 1年前
Noctis 1年前
╰ゝSakura 1年前
Noctis 1年前
boolstone 1年前
raybon 1年前

先把各种缓存加了吧,比如opencache,不行直接上webman,composer装过去无缝

1年前 评论
jingyu_wjy (楼主) 1年前

把抢购服务单独拉出来用swoole做服务端处理高频请求。 原来的业务结构不变。

1年前 评论
raybon 1年前

令牌桶 + 按照用户账号加锁 控制下进入的用户,限制每个用户ID 进入controller次数

1年前 评论

升级服务器配置 完美解决

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!