要稳定支撑1万并发,ThinkPHP6必须构建“缓存前置+异步卸载+常驻加速+分布式协同”四层防御体系:启用Swoole协程替代PHP-FPM,配置协程数据库连接池;分三级缓存(本地+Swoole Table、Redis带随机过期、布隆过滤器兜底);MySQL读写分离+查询熔断;非核心逻辑全异步化至队列处理。

ThinkPHP6 要稳定支撑 1 万并发,不能只靠框架微调,必须跳出 PHP-FPM 同步阻塞模型,构建“缓存前置 + 异步卸载 + 常驻加速 + 分布式协同”的四层防御体系。单纯加服务器或调大 pm.max_children 会迅速触发内存溢出、MySQL 连接耗尽、文件锁排队等连锁故障。
一、必须脱离 PHP-FPM,启用 Swoole 协程服务
TP6 原生是单请求生命周期,1 万并发在 FPM 下需至少 1000+ worker,内存和上下文切换直接崩溃。Swoole 是唯一可行路径:
- 用官方扩展
topthink/think-swoole启动,别手写裸 Server——它已封装 App 生命周期隔离、协程数据库连接池、Session/Cache 隔离机制 - 配置关键项:
'worker_num' => 4(匹配 CPU 核数),'max_coroutine' => 5000(协程数需 ≥ 并发峰值) - 数据库必须启用协程驱动:
'type' => 'mysql', 'hostname' => '127.0.0.1', 'hostport' => 3306, 'deploy' => 0, 'pool_size' => 200(连接池大小设为并发的 1/50~1/30) - 禁用所有文件类日志和调试中间件,日志改用
swoole_async写入或转发到 ELK
二、缓存必须分层且防穿透,Redis 不是万能解药
文件缓存(默认)在万级并发下因 flock 锁导致所有请求排队;全压 Redis 又可能击穿雪崩。要分三级:
-
本地缓存(L1):用
Swoole\Table或apcu缓存高频不变数据(如配置、状态码映射),毫秒级响应,零网络开销 -
Redis 缓存(L2):热点数据(用户登录态、商品库存)设随机过期时间(如
3600 + mt_rand(0,600)),避免集体失效;key 必须带业务前缀与版本号,如user:info:v2:10086 - 兜底缓存(L3):对极少数穿透请求(如恶意刷不存在的 ID),用布隆过滤器预判或空值缓存 5 分钟,防止打穿 DB
三、数据库必须读写分离 + 连接池 + 查询熔断
MySQL 默认 max_connections=151,1 万并发不加控制必报 1040 Too many connections:
- 主库只写,从库按权重分读;TP6 配置
'read_master' => false,并在中间件中根据路由规则动态选从库 - 连接池不是 TP6 自带功能,必须靠 Swoole 的
Co\MySQL池实现:Db::connect('mysql_pool')->query(...),池大小严格限制在 200 内 - 加查询熔断:用
Hyperf\CircuitBreaker或自研逻辑,当某 SQL 连续 5 次超时(>300ms),自动降级返回缓存或默认值,30 秒后半开试探 - 禁止事务嵌套、慎用
Db::transaction(),改用最终一致性 + 补偿事务
四、非核心逻辑全部异步化,用队列削峰填谷
登录成功发短信、下单后写操作日志、支付回调更新积分……这些耗时操作绝不能同步执行:
- 用 Redis List 或 Kafka 做消息队列,TP6 控制器内只推送任务 ID:
Redis::lPush('queue:notify', json_encode(['type'=>'sms','uid'=>10086])) - 独立部署多个 Worker 进程消费队列(用
topthink/think-worker),失败任务进延时重试队列(TTR 机制) - 前端接口立即返回
{"code":0,"msg":"已受理","request_id":"xxx"},状态通过 WebSocket 或轮询查 - 所有队列消费者关闭调试、禁用 ORM 自动加载,直连 PDO,减少内存占用
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











