Reputation: 1643
We are using MongoDB v4.2 on IBM Cloud over the Reactive MongoDB Driver v1.11. We are currently experiencing the following exception randomly, usually after some period of the app inactivity:
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
From what I've read and from what the JavaDoc gives for the driver - keepAlive
parameter is supposed to be set to true
by default.
But to be on the safe side - we are setting it explicitly:
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("xxx")))
.applyToSocketSettings(builder -> builder.keepAlive(true))
.build();
MongoClient client = MongoClients.create(settings);
But that does not seem to solve the issue. It occurs randomly and rarely. Any help is much appreciated
Upvotes: 3
Views: 1522
Reputation: 253
Setting the maxIdleTimeMS is the key here.
If you are using AbstractMongoClientConfiguration use the below code to set the maxIdleTimeMS on MongoClientSettings
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();
If you are using the now depreacted AbstractMongoConfiguration use the below code to set the maxConnectionIdleTime on MongoClientOptions
mongoClientOptions.maxConnectionIdleTime(x);
These changes will make sure that after the x milliseconds you set, the open connection will get closed and when a new request comes in to your service, a new connection is opened
Sample logs:
Closed connection [connectionId{localValue:3}] to host:27017 because it is past its maximum allowed idle time.
Opened connection [connectionId{localValue:4}] to host:27017
Upvotes: 1