H5 页面的核酸系统,前后端分离,前端 VUE ,后端 PHP 自己搭的 larave 框架,数据库 mysql,Nginx ,
三台负载均衡的天翼云应用服务器,都是 32 核 64G ,一台数据库服务器 16 核 32G ;
基本业务逻辑:
用户端,进入页面绑定自己身份证号手机号乡镇信息等个人信息,前端凭借身份证号直接生成个人二维码,向医护人员出示二维码,1 个小时需要做 40 万人口的核酸;
医护端,手机号身份证号登录或者申请,登入先选采集点,扫开箱码,再扫试管码选择十合一或二十合一,再点击添加人员打开扫一扫扫居民个人码添加;
24 日早上 4 点 30 ,医护人员开始大量的开始进入程序扫箱码开箱,并在后台开始大量的添加临时采集点,于 4 点 58 分,CPU 使用率 100%,系统崩溃,日志显示,瞬间请求数 1 万 4 ,重启在进入还是崩;
24 日下午系统整体挪到阿里云服务器,也是三台负载均衡的服务器,三台 32 核 64G ,加了 OSS ,用了阿里云的云数据库 RDS 版,主实例 8 核 16G ,只读数据库服务器 8 核,压测 10 分钟 15 万人,和 4000 医护人员同时在线也崩了,数据库和应用服务器的 CPU 利用率都打到了 100%,为了保障第二天不出问题,临时调大了一台应用服务器调到了 52 核,并同时把读写的两台数据库服务器都调到了最大 104 核,第二天检测才扛过去。
问:我们虽然调大了服务器的配置,但调大以后压测 10 分钟 20 万人和 4000 医护在线,服务器承载 20%都上不去,但前端页面会变得非常慢,基本上 10 几秒才能打开,这种情况请大神指点

嚯,没想到引发了热议,对语言和框架就不评判了,目前确定 opcache 生效后,DEBUG 关闭后,5 分钟 30 万读和 4700 医护人员同时开管扫码加人速度提高了 10 倍不止,目前程序每个接口运行 1.7S ,速度很快,感谢各位大佬

“确定 opcache 生效和 DEBUG 关闭后”这个是一个确定语句,伙计们,勿喷
具体做了,直接取 redis 缓存,不用直接操作数据库,只有在用户更换采集点的时候去修改下缓存,以及而且大量操作的时候添加了一下锁;

已解决,数据库调整一下,不用分库分表,做索引,优化下缓存就解决问题了,大佬们不用讨论框架的问题了,FPM 是没有问题的

关于 QPS ,回答大家一下,崩的时候 QPS 才 7K 多,崩的原因是请求数过高,瞬时 1 万 5 ,导致 CPU 过载

话说你们当时已经预料到会有高并发场景了,为啥还要考虑用 Laravel 写,不说 Swoole 了 Tp 都比这个快。。。

上 swoole

是否尝试把医护录入和居民数据库分开. 码数据加密缓存输出.

关键的部分使用更高性能的库重写,比如 swoole ,或者用 go 或者 java 。注意缓存和限流
larval 这种需要经过仔细调优才能达到很高的性能

主要是要找到瓶颈在哪,服务器内核调度也要针对性优化的,按道理 Laravel 没这么差劲

根据你说的,感觉后端好像也没瓶颈了... 前端的 js css 文件是从服务器获取? 全部挪动到 cdn 上试试?

收费分析系统,解决问题,你们接受不? 接受联系我

这个是历史遗留问题,一开始这个程序是单点预约检测的使用的业务逻辑,后来临时赶鸭子上架,改成了全民核酸的平台,没来得及

php 不懂,java 还是有很多解决方案的

Laravel 就不适合高并发,我们之前一次活动也被他坑了,后面用 go 重写了核心。

不要告诉我 你们的前端资源是直接访问的服务器。。。

php 异步框架,swoole 或者 workerman 这些

这种情况应该从应用层面去优化:

  1. 数据库服务器和应用服务器的 CPU 100%,可以看到什么是进程占用大量的 CPU 嘛
  2. 检查下 eloquent 是否有生成多余不用的 SQL 查询
  3. 检查下是否有把数据从 MySQL 取出来放到 PHP 里面做各种循环、统计等数据计算处理
  4. 检查下 MySQL 是否有查询没有走索引
  5. PHP 有没有 opcache
  6. Laravel Deployment Optimization 有没有做
  7. Nginx 的静态文件压缩有没有做
  8. Nginx 的静态文件缓存有没有做

nginx 是自己搭建的?一台?看看和 nginx 转发到其中一台后端服务时本地端口号用尽有没有关系?

瓶颈在接口请求,分析日志看到的是采集点调用的接口请求数量过高,递归把自己写死了,这个问题已经解决了,但压测的情况下,程序打开过于缓慢,这个问题不知道怎么解决

不是

打开慢,带宽打满了吗

用 Laravel 就是个最大的错误,benchmark 排名垫底的玩意来做高并发咋这么想不开呢

前端资源放 oss ?搞了单独的域名配 cdn 访问前端资源吗

程序打开过于缓慢需要先确认瓶颈在哪,大概率是 API 响应慢,开启 PHP-FPM 慢日志,看看是在哪一步慢。

另外就是调高 FPM 进程数,改成静态进程数,因为 FPM 自身的动态进程配置很难应对短时间内爆发增长的请求。

前端页面会变得非常慢,基本上 10 几秒才能打开
确认下前端资源是在 CDN 上还是在服务器上的,带宽是不是瓶颈

十合一或者二十合一可以不用一次性进数据库,先进缓存或者队列,慢慢进行消化,减少数据库的压力。

前端生成二维码的动作和医护扫描二维码的拆成两个站点,减轻压力

前端页面打开看看请求吧,有多少前端的多少后端的,哪些是可以降级或者不返回的

带宽 100M 的流量计费模式,高压测的情况下,带宽 50%也用不了

参考一下,laravel 上线优化清单。 learnku.com/laravel/t/24559
再查查数据库查询哪些地方能加缓存的,都加上。

对,前端资源都放在了 OSS ,没有用 CDN

没有往 Nginx 想,感谢,这个值得排查一些

这。。。cdn 用起来啊

实在不行,加上访问控制,慢点可以,别蹦了。

而且要域名直接访问 oss 别经过服务器

最关键的一点,你的 opcache 开了没? 之前有朋友一个服务器,是做微信小程序接口的,经常报警,负载能打到 90%,opcache 配好后,从来没超过 5% , 另外楼上说的 调高 FPM 进程数,改成静态进程数,也是必要的,你这么高的服务器配置,开 300 个进程是没问题的。
cdn 回源 oss

目测瓶颈在数据库字段索引上。建议前后端部署到不同的服务器上,前端高带宽,后端高性能。

那感觉还是得确定看看哪里慢,比如对某个 api 埋点观察执行时间;sql 执行慢就优化相关 sql 或使用缓存队列等;接口返回慢,可能是大量请求过来线程被占用不能及时处理请求,看看是否加大线程以及是否开启了会话保活机制,关闭以应对大并发....个人浅见

这些都有考虑到

CPU 利用率在哪部分? user sys 还是 io?

一会程序低频使用的时候,我们打开 PHP-FPM 慢日志低压测看一下

user sys

确定 opcache 生效了吧,那可能是慢 sql 导致每个请求过慢。 实在不行加个 swoole 扩展,laravel 现在官方支持 swoole 和 roadrunner ,配置进去可以试下。
可以写个 aliyun 的接口调用工具,高峰时动态扩容下机器。闲时再注销掉。

这个很久以前方便临时代理用的,可以简单参考下,现在的 SDK 可能变了。启动好后加 api 调用加到负载均衡里就可以了。

github.com/liuyibao/socks-proxy

你知道问题出在哪吗?是哪一步卡住了,那个页面有查询数据吗?现在是数据库高并发卡住了还是 PHP 处理数据卡住了?知道大概问题点更好分析一些,现在换框架可能来不及,不过有个 laravels 是 laravel + swoole 的框架,虽然不支持协程,但是性能应该比 laravel 好不少,关键切换过去,你代码几乎不用改。只是换了 PHP 的进程管理器。

laravel.com/docs/9.x/octane

实在不行是可以试下这个官方扩展

全是主观描述,多来点实际数据,不然不好给你看
参考具体 #32 说的指标

php:慢接口的 xhprof/tideways 输出给一下
系统 /linux: dstat 压测下和非压测下的输出给一下,dstat -amsy 1 30

其实很多时候都是数据库问题,试试优化数据库方式着手
还有前端应该上 cdn

打开 fpmstatus 看看

巅峰时期抓包看一下前端是慢在哪

现阶段可以考虑用 swoole 扩展一下,推荐 github.com/hhxsv5/laravel-s ,高并发还是推荐用 go

紧急的话可以先加上 github.com/hhxsv5/laravel-s 这样可以先抗住了.. 然后再加上缓存尤其是二维码那块

根据你的描述,PHP 应用服务器的问题不大,问题可能出现在前端资源加载和数据库上,前端资源走 cdn ,数据库的 sql 分析一下,应该能找到一些突破点

用多台小机器,而不是一台大机器,性能是不是好点?

带宽没跑满,服务器配置也够,我盲猜数据库吧,慢日志看看卡在哪里了

数据库都跑满了?我怀疑是短链接太多了导致的,建议你开代理池,这个阿里云本身就有的付费项目,减少频繁创建连接,数据库 cpu 下来之后,那剩下的就简单了,横向扩展,动态扩容加应用服务器,动态扩容也是阿里云自带的服务

#49 是的,不能只是纵向扩展,抗并发尽量横向扩展

前端资源放到 CDN ,后台上几层缓存,db 查询读缓存,写入放队列慢慢写。再上个容器负载均衡。不信这还扛不住

laravel 虽然慢, 但也没那么差, 个人觉得更大的可能性是数据库的问题
你们既然买了 rds,看下 rds 的性能分析, 看看什么 sql 语句导致的 cpu100%. 数据库慢, 会反向导致 php 服务器卡住爆满崩掉.
如果自己分析不出来, 联系阿里云运维客户, 让他们帮你们分析

跟我们的场景有点像
先上改成 laravel.com/docs/9.x/octane ,低版本用 laravel-s ;
数据库改 PolarDB ;
服务器这块改成 K8S 定时伸缩 ,方便还能省不少钱。

php 的性能没这么拉吧,问题应该在数据库,前面说的性能优化做到位,数据库缓存读,队列写,合并读写,看下 mysql slow query log 就知道了

装个 laravel-s

“服务器承载 20%都上不去,但前端页面会变得非常慢”,查一下 LBS 出口带宽,后端机器硬盘读写,fpm slow log, mysql slow log

1 、先检查数据库日志,定位下慢查询(数据库连接数满)
2 、Nginx 配置检查 gzip 压缩、静态资源过期设置(防止回源问题带来的压力)
3 、php-fpm ,进程静态配置很重要,Opcache 一定要开启来,慢日志问题也要定位解决(查找代码计算量大的问题点)
4 、前端静态资源必上 CDN ,回源 OSS 是最好的

这和 PHP 性能有什么关系? PHP 这部分 100%是个无状态服务,为什么你们在搞纵向扩展而不是横向扩展?非常令人疑惑。

用户端用户注册 //这个没啥好办法,直接数据库硬抗。
进入页面绑定自己身份证号手机号乡镇信息等个人信息 //这个环节加个 redis 队列,异步写入库操作。laravel 还是非常快速支持的。用户同步信息之后,把核心信息写入 redis hash 或者 string 都可以
前端凭借身份证号直接生成个人二维码, //这个环节对后端直接走缓存
向医护人员出示二维码,1 个小时需要做 40 万人口的核酸;//这个地方就完全走 cdn

像这种业务是非常适合引入 redis 这种缓存的。

忘记说了,我们是做了 redis 的

数据库都 100%的话肯定不光是 php 这头的问题,查问题先把死锁什么的问题排除吧。
web 端的问题直接 k8s ,硬抗就是了,之后再去慢慢调优,对于高计算量的功能点迁移到函数计算 fc 上去。

检查服务器日志和数据库日志(云服务和 rds 都有监控的)确定一下问题瓶颈是什么
如果是 php 这边的瓶颈: learnku.com/laravel/t/24559 (另外最重要的是 opcache ,如果兼容的话最好把 php 版本和 laravel 版本都提升上去)
如果是数据库的瓶颈: 先看慢查询日志,并发查询的语句,检查索引有没有。并发特别高的语句,临时加一个缓存应该也是很快实现的。

话说前端很慢,直接 f12 看看是请求静态资源慢还是请求接口慢呀

我也觉得瓶颈在数据库,按照你描述的业务,应该会经常访问到重复的数据,加层 redis 吧。

PHP 性能不至于这么拉胯,看看数据库问题,还有前端尽量和服务分开部署在不同服务器上,CDN 赶紧用上,Redis 也加上

一般我排查思路是这样的,
首先配置 nginx 日志,
接着就是 shell 脚本对 nginx 超时时间进行排序
查找超时且请求时间比较长的接口,
这时候你就要分析造成这种情况的原因了,
如果可以加缓存的话,就引入缓存,
其实就是查看数据库的查询情况,explain 一波。

一般情况下都是数据库使用不当引起的。
如果没法优化的话,那就稍微花点钱整个数据库主从分离。
服务器也是可以用平台的弹性伸缩。

基本上以上方法用了还不管用,
那就要考虑你们设计有问题了。

像这种业务应该不太会牵扯到多表联查这种情况

phper 的话高并发场景可以考虑 webman ,workerman 官方出品 数据库组件直接用的 laravel 的,无缝迁移。

框架是没法变的了、只能看看其他方面有没有优化的可能,我们最近也在高并发有些解决方案供参考

  • 降低高并发接口与数据库连接
  • 添加对应的数据库索引
  • nginx 压缩静态资源缓存
  • 高并发查询接口使用 redis 等缓存
  • 不及时响应数据丢 MQ 慢慢消费
  • 前端 cdn
  • 集群负载均衡等

例如我们注册的时候是个高并发、但是每次注册前会查询(select)下当前用户是否已注册过!然后在添加(insert)、后来我们就添加唯一索引、不查询,直接添加根据唯一索引的特性来判断最终处理结果、程序捕获异常!

还有一个高并发查询接口也是、因为数据并发没分每秒变动所以、我们用的 redis 缓存设置随机短期时间,但是高并发下会有雪崩穿透击穿的问题

你现在做的是对的,先做升级配置的 scale up ,撑着。
为什么卡住原因没有找到,感觉你的压测没有完全实现测试的目标,压测的目标是找到瓶颈点,不是证明你的并发能力。
你在 24 日下午压测,数据库和业务服务器都崩了,那么说明数据库扛不住,因为数据库崩了业务服务器肯定工作不了的。
从你最后压测服务器负载上不去的情况来看,目前瓶颈在数据库上。
是什么业务造成了数据库的压力?是写数据的压力还是读数据的压力?到底是什么动作带来数据库这么大的压力?是不是慢查询?能不能加缓存?是不是要做分库分表?短期内做一些数据完整性上的妥协是不是能快速降低压力?
你们做了压力测试但是没有找到问题,也没有提出解决方案。
从缓解数据库的压力来说,加 redis 做缓存可以快速解决问题但是最好预热数据,否则一到点并发大了依然会崩,最终可能还是要走向 sacle out 的分库分表。

scale up 和压测的路子都是对的,但是问题没找准,解决方案也就出不来。

我们虽然调大了服务器的配置,但调大以后压测 10 分钟 20 万人和 4000 医护在线,服务器承载 20%都上不去,但前端页面会变得非常慢,基本上 10 几秒才能打开

关于这点,你们可以把 web 服务器放到单独的服务器上边,前置一个负载均衡,然后你们就查看外网带宽的负载情况,不够就加带宽。然后就是静态资源放到 oss 上边加 cdn 。

尽量把前后端拆分开来,这样的话,职权更清晰,更容易排查问题。

善用日志,负载均衡有日志,第三方 oss 也是有监控日志的,分析下就定位问题了。

🤦‍♂️ 虽然很多人推荐 laravel-s 和 laravel-swoole ,但是还是鉴于目前的情况不建议赶鸭子上架,后续可以考虑再往这方面靠拢,包括 octane ,赶鸭子上架的话,你可能就有 1+N 个问题了。

现阶段可以根据各方面的慢日志:FPM 、MySQL 、Redis ,以及 Nginx 的日志来分析具体可能是哪些方面导致的问题。

阿里云服务器连接数没有改吧,默认 5000 不够,
关键是 redis 和 mysql 要开持久链接。
PHP 一个 fpm 默认只能服务一个请求。

有没有开启 opcache, 这个扩展可以极大的优化性能, 如果是 php-fpm 造成大量占用 cpu 的话可以解决一定的问题

还有 php-fpm 的性能配置, 优化的话可以极大的压榨性能;

接口复杂不, 不复杂其实还蛮推荐用 swoole 重写的, 有数据库连接池, 可以降低 mysql 的压力. 因为每个请求都会生成一个数据库连接. 连接池可以解决这个问题, 速度提升很明显. 少了连接和关闭的操作


另一个是 swoole 支持协程, 这个东西也是可以降低数据库压力, 可以让占用数据库连接的时间变短, 提升连接池的复用率


慢 sql 要查, 看看有些表字段是不是没加索引, 性能影响很拉胯的


redis 集群要用起来, 耗时长的任务不要阻塞等待了, 改成异步查结果. 用 kafka 或者 rabbitmq 做延迟任务处理.
(延迟任务这一块参考支付宝提现, 他会告诉你转账中. 倒计时 5 4 3 2 1, 然后再给你结果)

我能想到只有那么些

《解决 nginx+php/java/go/python+mysql 下 time_wait 连接数过多问题》

c4ys.com/archives/1609

'enableSchemaCache' => true,
'attributes' => [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_TIMEOUT => 1,
],

《 php redis 连接数过多解决办法( Yii,predis,phpredis 等)》

c4ys.com/archives/2421

'redis' => [
'class' => 'yii\redis\Connection',
'socketClientFlags' => STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT,
],

先看数据库 CPU ,
如果数据库 CPU 高,看数据库慢日志并优化索引,
如果数据库压力不高,看 WEB 服务器 PHP-FPM 日志,开启慢日志,优化慢方法,一般是循环太多或者调用第三方接口耗时。
查看连接数,使用持久链接,减少建立链接开销。

数据库的 CPU 都打满了?是不是一次性数据量处理太多了,有些数据被重复处理了?

在模拟环境装个 APM 看看调用慢在应该能直观反映问题,比如 tideways ,或者基于 tideways 的 php-monitor ,都可以统计出调用栈即调用耗时。

单纯就单体框架的性能排行榜而言,laravel 是几乎垫底的呀。怎么会选择它? lumen 都好那么一丢丢啊(因为前后分离)。

这种要 swoole 起步。

再看下 SQL 慢查呢,既然用了阿里云,他只带有慢 SQL 审计的,后面情况中服务器压测上不去,排除一下 DB 拖慢的可能性。

  1. 数据库主从和读写分离,一定要做,可以用现成的云服务(腾讯云有、阿里云也有),只需要在 laravel 的 config/database.php 里配置好,再引入 laravel 支持这样读写数据库的 package (有的,在官网文档里有)就可以运作
  2. 做二级缓存,也就是 Redis 或者 Memcache 。
  3. Sql 语法优化 —— 之所以提一下是没有必要做。再好的 Sql 语法,在并发到达临界线的时候都会全部卡死。只能重启 mysql 来解决。
  4. php-fpm 优化,做静态分配进程数,就是有个配置叫 pm=的那个,根据每个 php-fpm 子线程的占用内存计算出这台电脑最大的 php-fpm 进程数量,然后在 php-fpm 服务启动时就启动着么多个进程,避免使用动态进程过慢引起的并发问题。
  5. 做流量负载均衡,做外网访问服务的流量分发。可以用现成的云服务(腾讯云有、阿里云也有)。
  6. 改成微服务架构,由于功能没多少,该用 swoole 的同时改成微服务其实很快的。让每个模块独立化运作,由统一的 local gateway 做内网通信分发。
10 分钟 20 万人和 4000 医护在线
按这个数量级,并发数 1k 都不到,算不上「高并发」。
系统设计的好的话,单机 16C32G 带数据库都能撑住。

不了解 PHP 生态,但是作为一个主流成熟的框架,laravel 不至于连 1k 并发都撑不住。 → 不建议伤筋动骨换开发框架。

盲猜这些问题是设计开发没有质量管控,代码堆叠错乱导致的。
临时方案:先上个应用性能监控工具找出性能瓶颈吧,New Relic 或者 SkyWalking 之类,根据监控数据针对性地做优化、测试、压测。
长期方案:建立系统的软件质量管控体系。

laravel 现在有自带的 swoole 支持,Laravel Octane 。

数据库那边炸了的话应用服务器的确可能跟着炸(已经进来的请求卡在数据库查询上,还没进来的请求又排着队——你直说做了 LB ,没说限流的话我还是理解成你流量会全量打到应用服务器上的)

『但前端页面会变得非常慢,基本上 10 几秒才能打开』如果已经做了前后端分离,打开依然是白屏的那种慢,考虑上 CDN ,可能是你们的带宽到极限了。没做前后端分离那就要具体分析了,debug tool 看看是卡在 html 的返回( php 那继续优化,看看啥卡住了),还是前端资源卡住了(参考前后端分离时的方案)

還有遞歸?如果可以在中間加 message queue

绝对不是 php 的事
cpu 100%是等待数据库的线程积压的结果
1 个小时需要做 40 万人口,平均 1 秒钟也要 111 人,如果一直是单条入库,数据库肯定顶不住
使用批量入库或者用 redis 做中间层

1.核酸这种系统,居然用 PHP 。

2.应用服务器居然只有 3 台,还是虚拟化的云服务器,而且还只是 32C 64G 。

3.服务器居然也是虚拟化的云服务器,而且只有一台,还只是 32 核 64G 。

求求你们这些官僚资本主义,能放过人民群众吗?那个城市的?我能点举报吗?

系统竞标 200W ,实际总成本 20W ,人力成本 2W

php 用 swoole 罗 ,别用 laravel ,fpm 下 laravel 抗不了 用 hyperf swoft laravel-s 这些依赖 swoole 的 ,常驻内存性能就好很多了,加上协程 类似 golang 了

不是很理解,你们产品上线前没压测吗?自己能提供多少服务没数,为什么会出现生产中业务节点被压力打卦的情况。防火墙和任务队列应该先挂

用 laravel 做过并发 2k 的系统,ngx + php + redis + mysql ,需要优化的细节太多,犯错的机会也太多,静态语言确实能够通过编译系统检查和高性能的轮子规避一些问题,但是业务逻辑和程序设计模式的问题,同样也会出现
举个自己的例子,很早之前用 go + opencv 写过一个图片处理的程序,因为当时不熟悉 go 和 cv ,程序性能非常差,后来用 python 重写了,发现 py 有更完善的文档和更成熟应用,更多的社区支持

先从 sql 入手吧

哈哈,OP 空的时候记得 append 分享下最后原因和结果哦,v 友都热情帮你分析了

  • 阿里云的 rds ,不是有监控么?看看,db 是否有压力( cpu ,io )
  • db 看有没有慢 sql
  • db 没压力的话,ecs 有压力?那就水平扩展?
  • 静态资源 cdn

我先收藏一下,手上的项目日活 50w ,使用 php5.5 和 tp3 写的

二维码是前端生成的吗

1 .这么多地方 都在自建自己的 核酸二维码.... xx 人员也都想自建, 这可是活啊..😋

  1. 能上 cdn 都上 ,只是比 oss 多一点成本 . 尤其图片类的,多看看大小
  2. 查询那些全上 redis.
  3. php 临时换 go java 也来不及, 交钱找 swool 团队看看改造方案

小程序不复杂,没几个接口,直接 go java 重写吧,

这种很大概率是数据库索引有点问题 可以使用 overtrue/laravel-query-logger ,
在本地压测下 , 看日志里面那些语句执行时间长 ,
优先对查询时间长的对应语句使用下联合索引(复合索引 /混合索引)

哥哥,依赖 roadrunner 的 php 版本基本都要 8.0+,如果是旧项目,很难迁移重构的

另外 Redis 务必使用阿里云的云服务的 不要使用本机自建 因为读写性能受限的