In production we are connecting with a MongoDB using Java (connection pooling). Every day we are getting almost 500 requests with the error below (MongoSocketReadTimeoutException) and we are not using any complex query. Could it be stale Mongo connections?
I didn't see a problem with our code or MongoDB slowness. Please review my code below and suggest if any parameters need to be added or anything needs to be changed.
at 2018-03-07 19:52:43 ERROR ::Error while connecting the Mongo DB {}
com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message
at com.mongodb.connection.InternalStreamConnection.translateReadException(InternalStreamConnection.java:474)
at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:225)
at com.mongodb.connection.UsageTrackingInternalConnection.receiveMessage(UsageTrackingInternalConnection.java:102)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection.receiveMessage(DefaultConnectionPool.java:435)
at com.mongodb.connection.CommandProtocol.execute(CommandProtocol.java:112)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:159)
at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:286)
at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:173)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:215)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:206)
at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:112)
at com.mongodb.operation.FindOperation$1.call(FindOperation.java:487)
at com.mongodb.operation.FindOperation$1.call(FindOperation.java:482)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:239)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:212)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:482)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:79)
at com.mongodb.Mongo.execute(Mongo.java:772)
at com.mongodb.Mongo$2.execute(Mongo.java:759)
at com.mongodb.FindIterableImpl$FindOperationIterable.first(FindIterableImpl.java:207)
at com.mongodb.FindIterableImpl.first(FindIterableImpl.java:148)
at com.tecnotree.bom.validation.dao.MongoManager.getJsonObject(MongoManager.java:88)
at com.tecnotree.bom.validation.dao.CustomerMasterDao.getService(CustomerMasterDao.java:48)
at com.tecnotree.bom.validation.service.ValidationService.processValidation(ValidationService.java:214)
at com.tecnotree.bom.validation.service.ValidationService.processRequest(ValidationService.java:125)
at sun.reflect.GeneratedMethodAccessor185.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvid
er.java:205)
Code
public class ConnectionManager {
private ConnectionManager() {
}
private static final Logger logger = LoggerFactory.getLogger(ConnectionManager.class);
private static MongoClient mongoClient = null;
private static String connections = null;
private static String connectionTimeOut = null;
private static String socketTimeOut = null;
private static String serverSelectionTimeOut = null;
private static String URL = null;
private static String username = null;
private static String password = null;
private static String hostname = null;
private static String port = null;
private static String maxConnectionIdleTime = null;
private static String minConnectionsPerHost = null;
private static String maxConnectionLifeTime = null;
private static String dbName = null;
static {
dbName = ValidationProperties.getValue("clm.db.dbName");
mongoClient = getCLMSecondaryMongoConnection();
}
private static MongoClient getCLMSecondaryMongoConnection() {
connections = ValidationProperties.getValue("clm.db.connectionsPerHost");
connectionTimeOut = ValidationProperties.getValue("clm.db.connectTimeoutMS");
socketTimeOut = ValidationProperties.getValue("clm.db.socketTimeOut");
serverSelectionTimeOut = ValidationProperties.getValue("clm.db.serverSelectionTimeOut");
username = ValidationProperties.getValue("clm.db.userName");
password = ValidationProperties.getValue("clm.db.password");
hostname = ValidationProperties.getValue("clm.db.hostname");
port = ValidationProperties.getValue("clm.db.portnumber");
maxConnectionIdleTime = ValidationProperties.getValue("clm.db.maxConnectionIdleTime");
minConnectionsPerHost = ValidationProperties.getValue("clm.db.minConnectionsPerHost");
try {
List<MongoCredential> creds = new ArrayList<MongoCredential>();
creds.add(MongoCredential.createCredential(username, dbName, password.toCharArray()));
/*creds.add(MongoCredential.createMongoCRCredential(username, dbName, password.toCharArray()));*/
MongoClientOptions.Builder optionsBuilder = MongoClientOptions.builder();
optionsBuilder.connectTimeout(Integer.parseInt(connectionTimeOut));
optionsBuilder.serverSelectionTimeout(Integer.parseInt(serverSelectionTimeOut));
optionsBuilder.socketTimeout(Integer.parseInt(socketTimeOut));
optionsBuilder.connectionsPerHost(Integer.parseInt(connections));
optionsBuilder.maxConnectionIdleTime(Integer.parseInt(maxConnectionIdleTime));
optionsBuilder.minConnectionsPerHost(Integer.parseInt(minConnectionsPerHost));
if(Boolean.valueOf(ValidationProperties.getValue("clm.db.useSecondaryMongoForRead"))) {
logger.info("Read is going for secondary mongoDB");
optionsBuilder.readPreference(ReadPreference.secondaryPreferred());
}
MongoClientOptions options = optionsBuilder.build();
mongoClient = new MongoClient(new ServerAddress(hostname, Integer.parseInt(port)), creds, options);
} catch (Exception e) {
logger.error("Error while connecting the Mongo DB {}", e);
}
return mongoClient;
}
public static MongoClient getMongoClient() {
return mongoClient;
}