MongoDB云实例与JMeter连接失败求助
问题描述
尝试连接运行MongoDB实例的云服务器时,JMeter抛出以下超时异常:
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.internal.connection.SocketChannelStream.open(SocketChannelStream.java:63) ~[mongo-java-driver-3.9.1.jar:?]
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:126) ~[mongo-java-driver-3.9.1.jar:?]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117) ~[mongo-java-driver-3.9.1.jar:?]
at java.lang.Thread.run(Thread.java:831) ~[?:?]
Caused by: java.net.SocketTimeoutException: Connect timed out
at sun.nio.ch.SocketChannelImpl.finishTimedConnect(SocketChannelImpl.java:1143) ~[?:?]
at sun.nio.ch.SocketChannelImpl.blockingConnect(SocketChannelImpl.java:1181) ~[?:?]
at sun.nio.ch.SocketAdaptor.connect(SocketAdaptor.java:97) ~[?:?]
at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:64) ~[mongo-java-driver-3.9.1.jar:?]
at com.mongodb.internal.connection.SocketChannelStream.initializeSocketChannel(SocketChannelStream.java:72) ~[mongo-java-driver-3.9.1.jar:?]
at com.mongodb.internal.connection.SocketChannelStream.open(SocketChannelStream.java:60) ~[mongo-java-driver-3.9.1.jar:?]
... 3 more
已确认可通过VPN+SSL公钥连接该服务器,但JMeter连接失败,所有配置字段(mongoHost、mongoPort、databaseName、collectionName)均验证无误。
当前使用的JMeter连接脚本:
import com.mongodb.* import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClient; import com.mongodb.MongoClientSettings; import com.mongodb.ServerAddress; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; import java.util.Arrays; try { MongoClientSettings settings = MongoClientSettings.builder() .applyToClusterSettings {builder -> builder.hosts(Arrays.asList(new ServerAddress(vars.get("mongoHost"),vars.get("mongoPort").toInteger())))} .build(); MongoClient mongoClient = MongoClients.create(settings); MongoDatabase database = mongoClient.getDatabase(vars.get("databaseName")); MongoCollection<Document> collection = database.getCollection(vars.get("collectionName")); vars.putObject("collection", collection); return "Connected to " + vars.get("collectionName"); } catch (Exception e) { SampleResult.setSuccessful(false); SampleResult.setResponseCode("500"); SampleResult.setResponseMessage("Exception: " + e); }
解决方案
你的脚本确实缺少SSL认证相关配置,这是导致连接超时的核心原因。需要在MongoClientSettings中添加SSL上下文配置,指定SSL公钥文件路径:
1. 修改JMeter脚本,添加SSL配置
import com.mongodb.* import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClient; import com.mongodb.MongoClientSettings; import com.mongodb.ServerAddress; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; import java.util.Arrays; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import java.io.FileInputStream; import java.security.KeyStore; try { // 加载SSL公钥证书 String certPath = vars.get("sslCertPath"); // 提前在JMeter变量中配置公钥文件路径 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(new FileInputStream(certPath), null); // 证书无密码则传null TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); MongoClientSettings settings = MongoClientSettings.builder() .applyToClusterSettings {builder -> builder.hosts(Arrays.asList(new ServerAddress(vars.get("mongoHost"),vars.get("mongoPort").toInteger())))} .applyToSslSettings {sslBuilder -> sslBuilder.enabled(true) .context(sslContext) } .build(); MongoClient mongoClient = MongoClients.create(settings); MongoDatabase database = mongoClient.getDatabase(vars.get("databaseName")); MongoCollection<Document> collection = database.getCollection(vars.get("collectionName")); vars.putObject("collection", collection); return "Connected to " + vars.get("collectionName"); } catch (Exception e) { SampleResult.setSuccessful(false); SampleResult.setResponseCode("500"); SampleResult.setResponseMessage("Exception: " + e); }
2. 配置JMeter变量
确保在JMeter中添加以下变量:
sslCertPath:SSL公钥文件的绝对路径(例如/home/user/mongo-cert.pem)- 已有的
mongoHost、mongoPort、databaseName、collectionName保持不变
3. 额外检查项
- 确认JMeter运行环境已连接VPN,且网络路由能到达云服务器MongoDB端口
- 验证SSL公钥文件路径正确,文件权限允许JMeter读取
- 如果MongoDB实例需要用户名密码认证,需在
MongoClientSettings中添加认证配置:.credential(MongoCredential.createCredential( vars.get("username"), vars.get("databaseName"), vars.get("password").toCharArray() ))
内容的提问来源于stack exchange,提问作者Anish Mukherjee

