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

SpringBoot连接Mongo Atlas集群遇MongoSocket/UnknownHost异常求助

SpringBoot连接Mongo Atlas集群失败排查与解决

环境信息

  • Java 11
  • SpringBoot 2.5.5
  • MongoDB 6+

已在MongoDB Atlas中开放所有IP地址访问权限,但连接时抛出如下异常:

Timed out after 30000 ms while waiting to connect. Client view of cluster state is
{type=UNKNOWN, servers=[{address=CusterName:27017, type=UNKNOWN, state=CONNECTING,
exception={com.mongodb.MongoSocketException: CusterName}, caused by {java.net.UnknownHostException: CusterName}}];
nested exception is com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting to connect.
Client view of cluster state is {type=UNKNOWN, servers=[{address=CusterName:27017, type=UNKNOWN, state=CONNECTING,
exception={com.mongodb.MongoSocketException: CusterName}, caused by {java.net.UnknownHostException: CusterName}}]

连接池配置代码

import com.mongodb.*;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.connection.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoTransactionManager;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Configuration
public class MongoConnectionPool {

    @Bean
    @Autowired
    public MongoDatabaseFactory mongoFactory() {

        List<ServerAddress> serverAddresses = new ArrayList<>();

        String address = "<clusterName>:<port>";
        String[] hostAndPort = address.split(":");
        String host = hostAndPort[0];
        Integer port = Integer.parseInt(hostAndPort[1]);
        ServerAddress serverAddress = new ServerAddress(host, port);
        serverAddresses.add(serverAddress);
            
        ConnectionString connUrl = new ConnectionString("mongodb+srv://<username>:<password>@<clusterName>/<databaseName>");
        ConnectionPoolSettings poolSettings = ConnectionPoolSettings.builder()
                .maxWaitTime(100, TimeUnit.MILLISECONDS)
                .maxConnectionIdleTime(50, TimeUnit.MILLISECONDS)
                .maxConnectionLifeTime(30, TimeUnit.MILLISECONDS)
                .maxSize(12)
                .minSize(2)
                .build();
        ServerSettings serverSettings = ServerSettings.builder()
                .heartbeatFrequency(300, TimeUnit.MILLISECONDS)
                .minHeartbeatFrequency(100, TimeUnit.MILLISECONDS)
                .build();
        ClusterSettings clusterSettings = ClusterSettings.builder()
                .hosts(serverAddresses)
                .localThreshold(200, TimeUnit.MILLISECONDS)
                .serverSelectionTimeout(250, TimeUnit.MILLISECONDS)
                .requiredClusterType(ClusterType.REPLICA_SET)
                .mode(ClusterConnectionMode.SINGLE)
                .requiredReplicaSetName("rs0")
                .build();
        SocketSettings socketSettings = SocketSettings.builder()
                .connectTimeout(100, TimeUnit.MILLISECONDS)
                .readTimeout(50, TimeUnit.MILLISECONDS)
                .build();
        SslSettings sslSettings = SslSettings.builder()
                .enabled(false)
                .invalidHostNameAllowed(false)
                .build();
        MongoClientSettings settings = MongoClientSettings.builder()
                .applyConnectionString(connUrl)
                .applyToClusterSettings(builder -> builder.applySettings(clusterSettings))
                .applyToConnectionPoolSettings(builder -> builder.applySettings(poolSettings))
                .applyToServerSettings(builder -> builder.applySettings(serverSettings))
                .applyToSocketSettings(builder -> builder.applySettings(socketSettings))
                .applyToSslSettings(builder -> builder.applySettings(sslSettings))
                .readPreference(ReadPreference.primary())
                .build();

        MongoClient mongoClient = MongoClients.create(settings);
        return new SimpleMongoClientDatabaseFactory(mongoClient, "<databaseName>");
    }

    @Bean
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }

}

排查思路与解决建议

1. 核心问题:主机名解析失败

异常中的UnknownHostException是关键,说明客户端无法识别集群的主机地址:

  • 替换代码中<clusterName>为Mongo Atlas提供的完整集群域名(例如cluster0.mongodb.net),不能仅填写自定义集群名称;
  • 在应用服务器上执行nslookup <集群完整域名>,验证DNS能否正常解析出IP,若失败检查服务器DNS配置或网络连通性。

2. 配置冲突:手动集群设置覆盖自动发现逻辑

代码同时使用了ConnectionString(mongodb+srv协议)和手动构建的ClusterSettings,导致冲突:

  • mongodb+srv协议会自动解析集群节点、副本集信息,手动指定hosts、ClusterConnectionMode.SINGLE会覆盖该逻辑;
  • 删除所有ServerAddress、ClusterSettings相关代码,让驱动通过srv协议自动完成集群发现。

3. SSL配置错误:Atlas强制要求SSL连接

代码中设置sslSettings.enabled(false)违反Atlas的连接规则:

  • 将SSL配置改为enabled(true),或直接删除手动的SslSettings配置(mongodb+srv协议默认启用SSL)。

4. 超时参数设置不合理

代码中超时参数过短(如连接超时100ms),极易触发超时:

  • 调整为合理值:
    • connectTimeout改为3000ms(3秒)
    • serverSelectionTimeout改为10000ms(10秒)
    • maxWaitTime改为5000ms(5秒)
  • 连接池的maxConnectionIdleTime、maxConnectionLifeTime建议设置为分钟级别(如30分钟、1小时),毫秒级别会导致连接频繁销毁重建。

5. 依赖兼容性检查

SpringBoot 2.5.5对应Spring Data MongoDB 3.2.x,需确保Mongo Java驱动与MongoDB 6.x兼容:

  • 检查依赖文件中mongodb-driver-sync版本,建议使用4.4.x及以上(SpringBoot 2.5.5默认4.3.x也可兼容,升级更稳定)。

简化后的配置示例

@Configuration
public class MongoConnectionPool {

    @Bean
    public MongoDatabaseFactory mongoFactory() {
        ConnectionString connUrl = new ConnectionString("mongodb+srv://<username>:<password>@<集群完整域名>/<databaseName>?retryWrites=true&w=majority");
        
        ConnectionPoolSettings poolSettings = ConnectionPoolSettings.builder()
                .maxWaitTime(5, TimeUnit.SECONDS)
                .maxConnectionIdleTime(30, TimeUnit.MINUTES)
                .maxConnectionLifeTime(1, TimeUnit.HOURS)
                .maxSize(12)
                .minSize(2)
                .build();

        MongoClientSettings settings = MongoClientSettings.builder()
                .applyConnectionString(connUrl)
                .applyToConnectionPoolSettings(builder -> builder.applySettings(poolSettings))
                .readPreference(ReadPreference.primary())
                .build();

        MongoClient mongoClient = MongoClients.create(settings);
        return new SimpleMongoClientDatabaseFactory(mongoClient, "<databaseName>");
    }

    @Bean
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }

}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 13:17:18