MongoDB随机异常

问题描述 投票:0回答:1

我们正在通过Reactive MongoDB Driver v1.11在IBM Cloud上使用MongoDB v4.2。目前,我们通常会在一段时间不使用应用程序后随机遇到以下异常:

com.mongodb.MongoSocketWriteException: Exception sending message
    at com.mongodb.internal.connection.InternalStreamConnection.translateWriteException(InternalStreamConnection.java:541)
    at com.mongodb.internal.connection.InternalStreamConnection.access$1100(InternalStreamConnection.java:74)
    at com.mongodb.internal.connection.InternalStreamConnection$3.failed(InternalStreamConnection.java:470)
    at com.mongodb.internal.connection.AsynchronousChannelStream$1.failed(AsynchronousChannelStream.java:97)
    at com.mongodb.internal.connection.AsynchronousChannelStream$2.failed(AsynchronousChannelStream.java:173)
    at com.mongodb.internal.connection.AsynchronousChannelStream$AsyncWritableByteChannelAdapter$WriteCompletionHandler.failed(AsynchronousChannelStream.java:198)
    at com.mongodb.internal.connection.tlschannel.async.AsynchronousTlsChannel$10$1.run(AsynchronousTlsChannel.java:269)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Connection reset by peer
    at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
    at sun.nio.ch.IOUtil.write(IOUtil.java:65)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
    at com.mongodb.internal.connection.tlschannel.impl.TlsChannelImpl.writeToChannel(TlsChannelImpl.java:479)
    at com.mongodb.internal.connection.tlschannel.impl.TlsChannelImpl.writeToChannel(TlsChannelImpl.java:464)
    at com.mongodb.internal.connection.tlschannel.impl.TlsChannelImpl.wrapAndWrite(TlsChannelImpl.java:403)
    at com.mongodb.internal.connection.tlschannel.impl.TlsChannelImpl.write(TlsChannelImpl.java:391)
    at com.mongodb.internal.connection.tlschannel.ClientTlsChannel.write(ClientTlsChannel.java:181)
    at com.mongodb.internal.connection.tlschannel.async.AsynchronousTlsChannelGroup.writeHandlingTasks(AsynchronousTlsChannelGroup.java:553)
    at com.mongodb.internal.connection.tlschannel.async.AsynchronousTlsChannelGroup.doWrite(AsynchronousTlsChannelGroup.java:501)
    at com.mongodb.internal.connection.tlschannel.async.AsynchronousTlsChannelGroup.access$400(AsynchronousTlsChannelGroup.java:67)
    at com.mongodb.internal.connection.tlschannel.async.AsynchronousTlsChannelGroup$6.run(AsynchronousTlsChannelGroup.java:459)
    ... 3 more

根据我所阅读的内容以及JavaDoc为驱动程序提供的内容-keepAlive参数默认情况下应设置为true。但是为了安全起见-我们正在对其进行明确设置:

MongoClientSettings settings = MongoClientSettings.builder()
    .applyConnectionString(new ConnectionString("xxx")))
    .applyToSocketSettings(builder -> builder.keepAlive(true))
    .build();
MongoClient client = MongoClients.create(settings);

但是这似乎无法解决问题。它是随机发生的,很少发生。任何帮助都非常感谢

java mongodb mongo-java mongo-java-driver
1个回答
0
投票

这里设置maxIdleTimeMS是关键。仅供参考,我正在使用spring-data-mongodb 2.5.5-RELEASE

如果使用的是AbstractMongoClientConfiguration,请使用以下代码在MongoClientSettings上设置maxIdleTimeMS

SSLContext.setDefault(sslContext);
**String connectionTemplateString = "mongodb://%s:%s@%s/%s?maxIdleTimeMS=%s";**
String clusterEndpoint = dbHost + ":" + port;
String maxIdleTimeInMs = "x";
String connectionString = String.format(connectionTemplateString, dbUser, dbPassword, clusterEndpoint,dbName, maxIdleTimeInMs);
ConnectionString connString = new ConnectionString(connectionString);
mongoClientSettings = MongoClientSettings.builder().applyConnectionString(connString)
                    .applyToSslSettings(builder -> {
                        builder.enabled(true);
                        builder.invalidHostNameAllowed(true);
                        builder.context(sslContext);
                    }).build();

如果使用的是现在已弃用的AbstractMongoConfiguration,请使用以下代码在MongoClientOptions上设置maxConnectionIdleTime。>

**mongoClientOptions.maxConnectionIdleTime(x);**

这些更改将确保在您设置的x毫秒后,打开的连接将被关闭,并且当新的请求进入您的服务时,将打开一个新的连接。

示例日志:

  1. x毫秒后
  2. 与主机:27017的关闭连接[connectionId {localValue:3}],因为它超出了其允许的最大空闲时间。

  1. 收到新请求时
  2. 打开到主机的连接[connectionId {localValue:4}]:27017

© www.soinside.com 2019 - 2024. All rights reserved.