Webman 连不上 MongoDB 主因是 PHP CLI 环境未启用 mongodb 扩展,需检查 php -m、php --ini 及 Docker 中 pecl 安装;应直连 MongoDB\Client 而非依赖 jenssegers 封装,并配置连接池与超时;索引需匹配查询顺序,缓存需按物理内存合理设置。

Webman 项目里连不上 MongoDB,90% 不是代码写错了,而是 PHP CLI 环境根本没装 mongodb 扩展,或者扩展加载了但配置错位。
确认 php-cli 是否真正加载了 mongodb 扩展
Webman 的启动、定时任务、命令行导入数据,全部走的是 php-cli,和 Web 请求用的 php-fpm 完全是两套环境。改了 php-fpm 的 php.ini,对 Webman 启动毫无作用。
- 执行
php -m | grep mongodb,无输出 → 扩展未启用 - 执行
php --ini查看Loaded Configuration File路径,打开对应php.ini,确认存在extension=mongodb(不是extension=php_mongo.dll,那是旧版驱动) - Docker 用户必须在
Dockerfile中显式安装扩展:pecl install mongodb+docker-php-ext-enable mongodb,仅composer require jenssegers/mongodb完全没用
用原生 MongoDB\Client 连接,别依赖 jenssegers/mongodb 封装
jenssegers/mongodb 是 Laravel 适配层,Webman 里直接用它容易踩隐性坑:连接复用混乱、超时参数不生效、批量操作被转成低效单条调用。真要稳定,就绕过封装,直连。
- 连接示例(带认证、连接池、超时):
$client = new \MongoDB\Client( 'mongodb://user:pass@127.0.0.1:27017', [ 'connectTimeoutMS' => 5000, 'socketTimeoutMS' => 30000, 'maxIdleTimeMS' => 60000, 'minPoolSize' => 5, 'maxPoolSize' => 20 ] ); $collection = $client->mydb->mycollection; - 不要在每次请求中 new Client,应作为容器服务单例注入,避免反复建连
- 若用副本集,连接字符串必须带
?replicaSet=rs0,否则写入可能静默失败
查慢查询前先跑 explain("executionStats")
Webman 查 100 万条订单按 status 和 created_at 分页很慢?别急着加索引,先看是否命中了索引扫描(IXSCAN),还是在全表扫(COLLSCAN)。
立即学习“PHP免费学习笔记(深入)”;
- 在 MongoDB Shell 中执行:
db.orders.find({status:"paid"}).sort({created_at:-1}).limit(20).explain("executionStats") - 重点看:
executionStats.executionStages.stage === "IXSCAN",且executionStats.nReturned接近executionStats.totalDocsExamined - 如果
totalDocsExamined是几万,nReturned只有 20,说明索引没覆盖查询字段,得补投影:->project(['id', 'amount', 'status', 'created_at']) - 复合索引必须严格匹配查询顺序:
{status: 1, created_at: -1}支持status = ?+sort(created_at),但不支持只查created_at > ?
Webman 多 worker 下 WiredTiger cacheSizeGB 别乱设
Webman 默认开 4~8 个 worker,每个都连同一个 MongoDB 实例,但 cacheSizeGB 是整个 mongod 进程的全局缓存上限。设高了,OS 内存吃紧;设低了,缓存频繁淘汰,查询毛刺明显。
- 查当前使用率:
db.serverStatus().wiredTiger.cache["bytes currently in the cache"] / db.serverStatus().wiredTiger.cache["maximum bytes configured"] - 生产环境建议值 = 物理内存 × 55%~60%,例如 32GB 机器设
cacheSizeGB: 18(不是 20) - 如果
tracked dirty bytes in the cache持续 >20%,说明刷盘压力大,可加配置eviction=(threads_max=8),但仅限 MongoDB 4.0+ 副本集
索引和缓存配置没有“通用最优值”,只有和你的查询模式、内存水位、写入节奏对齐才真正有效。上线前务必用真实数据量压测,别信默认配置或二手经验。



















