2

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;
    }
THelper
  • 15,333
  • 6
  • 64
  • 104
Narasimha
  • 109
  • 2
  • 13

2 Answers2

0

In your code you are setting various MongoClientOptions, but you do not say what values you are using. Most likely one of the settings is causing the problem. My first guess would be that socketTimeout is too small, my second guess would be that connectionsPerHost is smaller than the maximum number of concurrent requests you receive in production.

I assume that testing in your production environment is not an option, so the first thing you should do is try and reproduce the problem in a test environment. You can use the free JMeter tool to reproduce a certain load to your server. Use it's ramp-up feature to see if your problems start once you reach a certain load or if they occur at random.

If you still have trouble finding out what exactly causes the problems, you can also try to comment out all your optionBuilder settings (so you'll be using all default settings). If that fixes the problem, then you can set back your configuration options one-at-a-time to see which is the problematic one.

THelper
  • 15,333
  • 6
  • 64
  • 104
0

You must remove hibernate dependency from your project.
I faced this problem and that was the solution.

develth
  • 771
  • 8
  • 32
Dali
  • 13
  • 5