You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题分析与解决

  1. 关于+srv与端口的说明:mongodb+srv://的作用是通过SRV查询自动获取集群节点的地址和默认端口(27017),错误里的端口是正常解析结果,不需要覆盖。

  2. 连接失败的核心排查方向:

    • 端口权限: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是否与实际集群域名一致。
  3. 脚本输出的uri变化:Manager输出的mongodb://是正常现象,因为+srv只是解析协议,内部会转换成标准mongodb格式,不影响功能。


内容的提问来源于stack exchange,提问作者yogibear

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:32:47