PHP使用MongoDB+srv执行BulkWrite时出现连接超时错误求助
PHP脚本执行MongoDB BulkWrite时的连接超时问题
错误日志
[russell@hawk mongo]$ cat error_log [29-Apr-2023 05:04:22 UTC] PHP Fatal error: Uncaught MongoDB\Driver\Exception\ConnectionTimeoutException: No suitable servers found (`serverSelectionTryOnce` set): [connection closed calling ismaster on 'cluster0-shard-00-00.tx3cl.mongodb.net:27017'] [connection closed calling ismaster on 'cluster0-shard-00-01.tx3cl.mongodb.net:27017'] [connection closed calling ismaster on 'cluster0-shard-00-02.tx3cl.mongodb.net:27017'] in /home/mongo/2_test_mongo.php:13 Stack trace: #0 /home/mongo/2_test_mongo.php(13): MongoDB\Driver\Manager->executeBulkWrite() #1 {main} thrown in /home/mongo/2_test_mongo.php on line 13
疑问点
错误信息里显示了端口号27017,但我使用的是mongodb+srv://连接字符串——这种连接方式不允许手动指定端口,我也没添加过端口。另外:
- 在本地Compass中去掉
+srv,会报getaddrinfo ENOTFOUND cluster0.tx3cl.mongodb.net错误; - 用端口27017替代
+srv,同样会出现该错误。
想问是否需要设置来覆盖自动添加的默认端口?
技术细节
[prompt]$ php --version PHP 8.0.18 (cli) (built: Apr 13 2022 10:54:57) ( NTS ) Copyright (c) The PHP Group Zend Engine v4.0.18, Copyright (c) Zend Technologies [prompt]$ uname -a Linux blah.blah.net 3.10.0-962.3.2.lve1.5.67.el7.x86_64 #1 SMP Fri Mar 25 07:13:21 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
脚本执行输出
[prompt]$ php script.php loaded MongoDB\Driver\Manager Object ( [uri] => mongodb://user:password@blah.blah.mongodb.net/?retryWrites=true&w=majority [cluster] => Array ( ) )
脚本代码
<?php use MongoDB\Client; use MongoDB\Driver\ServerApi; echo extension_loaded("mongodb") ? "loaded\n" : "not loaded\n"; $uri = 'mongodb+srv://user:password@blah.blah.mongodb.net/?retryWrites=true&w=majority'; $manager = new MongoDB\Driver\Manager($uri); print_r($manager); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(['x' => 1]); $bulk->insert(['x' => 2]); $bulk->insert(['x' => 3]); $manager->executeBulkWrite('TestyDB.TestyCollection', $bulk); $filter = ['x' => ['$gt' => 1]]; $options = [ 'projection' => ['_id' => 0], 'sort' => ['x' => -1], ]; $query = new MongoDB\Driver\Query($filter, $options); $cursor = $manager->executeQuery('TestyDB.TestyCollection', $query); foreach ($cursor as $document) { var_dump($document); } ?>
网络连通性测试
russell@hawk mongo]$ ping cluster0-shard-00-00.tx3cl.mongodb.net PING ec2-52-55-183-242.compute-1.amazonaws.com (52.55.183.242) 56(84) bytes of data. 64 bytes from ec2-52-55-183-242.compute-1.amazonaws.com (52.55.183.242): icmp_seq=1 ttl=228 time=76.7 ms 64 bytes from ec2-52-55-183-242.compute-1.amazonaws.com (52.55.183.242): icmp_seq=2 ttl=228 time=76.7 ms 64 bytes from ec2-52-55-183-242.compute-1.amazonaws.com (52.55.183.242): icmp_seq=3 ttl=228 time=76.7 ms 64 bytes from ec2-52-55-183-242.compute-1.amazonaws.com (52.55.183.242): icmp_seq=4 ttl=228 time=76.7 ms 64 bytes from ec2-52-55-183-242.compute-1.amazonaws.com (52.55.183.242): icmp_seq=5 ttl=228 time=76.6 ms
问题分析与解决
关于+srv与端口的说明:
mongodb+srv://的作用是通过SRV查询自动获取集群节点的地址和默认端口(27017),错误里的端口是正常解析结果,不需要覆盖。连接失败的核心排查方向:
- 端口权限:ping通仅说明ICMP可达,需确认服务器防火墙/安全组是否允许TCP 27017端口的出站访问;
- 白名单配置:如果是MongoDB Atlas集群,检查集群IP白名单是否包含当前服务器的公网IP,这是最常见的连接失败原因;
- 扩展兼容性:升级PHP的MongoDB扩展到最新稳定版,确保与集群版本兼容;
- Server API指定:在连接时显式指定Server API版本,避免兼容性问题:
$serverApi = new ServerApi(ServerApi::VERSION_1); $manager = new MongoDB\Driver\Manager($uri, [], ['serverApi' => $serverApi]); - SSL配置:SRV连接默认要求SSL,确认PHP是否配置了正确的CA证书,或在连接选项中添加
ssl=true显式开启; - 域名正确性:错误中的集群域名为
cluster0-shard-xxx.tx3cl.mongodb.net,检查脚本里的blah.blah.mongodb.net是否与实际集群域名一致。
脚本输出的uri变化:
Manager输出的mongodb://是正常现象,因为+srv只是解析协议,内部会转换成标准mongodb格式,不影响功能。
内容的提问来源于stack exchange,提问作者yogibear
相关产品推荐
相关产品推荐

