MongoSocketReadException: Prematurely reached end of stream (after a period of inactivity)

前端 未结 6 1909
Happy的楠姐
Happy的楠姐 2020-12-05 02:34

I get this error on a find call (default Java Driver) after a period of inactivity. I tried to add a manual heartbeat (writing to a capped collection), but it d

相关标签:
6条回答
  • 2020-12-05 03:16

    The problem is that Mongodb end the connection. You need to increase the timeout of the Mongodb Driver here is an example code.

     MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
        //build the connection options
        builder.maxConnectionIdleTime(86400000);//set the max wait time in (ms)
        MongoClientOptions opts = builder.build();
    
    
    
    
        final Morphia morphia = new Morphia();
    
    
        morphia.mapPackage("com.java.code");
    
    
        final String hostURL = "host_url";
                
    
        MongoCredential  credential = MongoCredential.createCredential("username","database","Password".toCharArray()); 
    
        ServerAddress address = new ServerAddress(hostURL);
    
    
        List<MongoCredential> credentialList = new ArrayList<>();
        credentialList.add(credential);
    
    
       final MongoClient client = new MongoClient(address,credentialList,opts);
    
    
    
    
        // create the Datastore connecting to the default port on the local host
        datastore  = morphia.createDatastore(client,"datastore");
    
    0 讨论(0)
  • 2020-12-05 03:19

    To me it was a whole different issue - I was using mongo-java-server with Fongo and ended up getting this error. Turns out that old versions of it are not compatible with FieldType.DECIMAL128 conversions.

    Updating it to the latest one (1.36.0 currently) fixed the issue for me.

    0 讨论(0)
  • 2020-12-05 03:24

    I solve this problem by set sslEnabled to true,code sample:

    @Bean
    public MongoClient mongoClient() {
        List<ServerAddress> saList = new ArrayList<>();
        saList.add(new ServerAddress("cluster0-shard-00-00-75shm.gcp.mongodb.net", 27017));
        saList.add(new ServerAddress("cluster0-shard-00-01-75shm.gcp.mongodb.net", 27017));
        saList.add(new ServerAddress("cluster0-shard-00-02-75shm.gcp.mongodb.net", 27017));
    
        char[] pwd =  "password".toCharArray();
        MongoCredential credential = MongoCredential.createCredential("username", "admin", pwd);
    
        //set sslEnabled to true here
        MongoClientOptions options = MongoClientOptions.builder()
                .readPreference(ReadPreference.primaryPreferred())
                .retryWrites(true)
                .requiredReplicaSetName("Cluster0-shard-0")
                .maxConnectionIdleTime(6000)
                .sslEnabled(true)
                .build();
    
        MongoClient mongoClient = new MongoClient(saList, credential, options);     
        return mongoClient;
    }
    

    Addition: my client jar is org.mongodb.mongodb-driver 3.6.4,server is mongodb atlas M0 3.6.6 on GCP

    0 讨论(0)
  • 2020-12-05 03:28

    I agree with Rhangaun's answer here is my soluction in code of JAVA:

        public static DB getMongoDB() {
    
            MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
            //build the connection options  
            builder.maxConnectionIdleTime(60000);//set the max wait time in (ms)
            MongoClientOptions opts = builder.build();
    
    
            char[] password2 = "mypassword".toCharArray();
    
            MongoCredential credential2 = MongoCredential.createCredential("username", "databasename",password2);
    
    
            //add your option to the connection 
    
            MongoClient mongoClient = new MongoClient(new ServerAddress("server ip",27017), Arrays.asList(credential2),opts);
            //use your database 
            cachedDb = mongoClient.getDB("databasename");
    
        return cachedDb;
    
    }
    

    Here is my research link:http://3t.io/blog/how-to-prevent-your-connection-from-dropping-with-hosted-mongodb-instances/

    Hope it helps you.

    0 讨论(0)
  • 2020-12-05 03:33

    I found it in some documentation:

    For long running applications, it is often prudent to enable "keepAlive" with a number of milliseconds. Without it, after some period of time you may start to see "connection closed" errors for what seems like no reason.

    Check if this helps. When you connect to mongoDB you can pass socket options to it. I am from node background we use following options to keep it alive.

    server: {
            socketOptions: {
                keepAlive: 100,
                connectTimeoutMS: 30000
            }
        }
    

    Hope this helps!!

    0 讨论(0)
  • 2020-12-05 03:37

    This worked for me in spring boot and cloud based mongo (Atlas clustered instances).

    Edit application.properties like this:

    spring.data.mongodb.uri = mongodb+srv://username:password@solarsystem-1tpu0.mongodb.net/dbname
    

    For regular mongo instances (non-clustered) use this:

    spring.data.mongodb.uri = mongodb://username:password@solarsystem-shard-00-00-1tpu0.mongodb.net:27017,hostname2:27017/dbname?ssl=true
    
    • If you want to set other connection options, you can chain multiple parameters using '&' ; documentation here: https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClientURI.html
    • If you were using other spring.data.mongodb parameters, you should remove all of them otherwise spring won't read spring.data.mongodb.uri
    0 讨论(0)
提交回复
热议问题