thinkphp 6 稳定支撑 1 万并发读请求需叠加连接池、轮询负载、故障跳过和业务兜底四层能力;主从配置须启用 deploy=1 和 rw_separate=true,从库必须二维数组,统一参数,并重写 getreadconnection 实现轮询+异常跳过。

ThinkPHP 6 要稳定支撑 1 万并发读请求,单靠基础读写分离配置远远不够。核心不是“能不能分”,而是“分得准、连得稳、扛得住、不拖后腿”。主从配置只是起点,高并发下必须叠加连接池、负载策略、故障应对和业务兜底四层能力。
主从配置必须严格符合 TP6 规范
很多项目卡在第一步:配置写了但没生效。TP6 不会自动识别多地址,必须显式启用开关并结构化定义节点。
-
必须同时开启两个开关:在
config/database.php的connections['mysql']块内,明确写入'deploy' => 1和'rw_separate' => true;这两个键不能放在顶层或 default 下,否则无效 -
主库只能是单数组,从库必须是二维数组:write 不支持数组,read 必须是
['slave' => [['hostname' => '192.168.1.11', ...], ['hostname' => '192.168.1.12', ...]]];哪怕只配一个从库,也得套一层数组,否则报错Call to a member function query() on null -
所有节点 database 名必须完全一致,字符集(
charset)、端口(hostport)、前缀(prefix)等参数需统一,避免跨库 JOIN 或缓存失效问题
默认随机选从库不行,必须改轮询+异常跳过
TP6 默认用 array_rand() 随机选从库,1 万并发下容易出现某台从库瞬时打满、另一台空闲,且节点宕机后仍可能被选中导致请求失败。
- 新建
app/common/db/RoundRobinConnection.php,继承think\db\Connection - 重写
getReadConnection()方法,用静态变量记录索引,每次 +1 取模,实现 db1→db2→db3→db1 的严格轮询 - 在轮询逻辑中加入
try/catch,连接失败时自动跳过当前节点,继续尝试下一个,避免单点故障阻塞整个读链路 - 在 database.php 中通过
'connection' => \app\common\db\RoundRobinConnection::class指向该类
连接池与协程支持是并发承载关键
传统 PDO 连接在 1 万并发下极易耗尽 MySQL 连接数(max_connections 默认常为 151),必须引入连接复用机制。
- 若使用 Swoole,配置
'pool_size' => 200(建议设为主从总节点数 × 50~80),并开启'break_reconnect' => true - 启用 OPcache 和 realpath_cache,关闭调试模式(
APP_DEBUG = false),减少每次请求的文件解析开销 - 对高频查询加 Redis 缓存,降低从库压力;注意清空
runtime/cache和 schema 缓存,防止旧配置残留 - 避免在事务中执行纯读操作——TP6 事务内所有查询强制走主库,会瞬间压垮主库
业务层必须做延迟与一致性兜底
主从复制存在毫秒级延迟,1 万并发下极易出现“刚写完查不到”问题,框架不解决,只能由业务控制。
- 对强一致性场景(如用户注册后立即跳转个人页),写操作后主动调用
->master()查主库,例如:Db::name('user')->master()->where('id', $id)->find() - 对非关键读取(如文章浏览量、日志列表),允许短暂延迟,直接走从库即可
- 不要依赖
getLastSql()判断路由是否生效——它显示的是最终执行语句,不反映连接选择过程;可用Db::getConnection()->getConfig()打印当前连接信息验证 - 监控从库延迟(
SHOW SLAVE STATUS\G中的Seconds_Behind_Master),超 500ms 时可临时降级为全走主库,或触发告警人工介入
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











