MongoSocketReadException: преждевременно достигнут конец потока (после периода бездействия)

Я получаю эту ошибку при вызове find (драйвер Java по умолчанию) после периода бездействия. Я попытался добавить ручное сердцебиение (запись в ограниченную коллекцию), но это не помогло. У меня проблема возникает только при подключении к экземпляру при составлении (т.е. не в локальном контексте).

Версия MongoDB - 3.2.8, последний драйвер (3.3) с использованием Java 8.

Любая идея ?


person Rhangaun    schedule 22.08.2016    source источник
comment
Я обнаружил, что флаг isSocketKeepAlive для MongoClientOptions по умолчанию равен false, я изменил его на true и теперь жду, получу ли я ошибку снова.   -  person Rhangaun    schedule 07.09.2016
comment
к сожалению, с .socketKeepAlive (true) мы также получаем эту ошибку, моя версия диска - 3.0.4   -  person Feng    schedule 14.09.2016
comment
смогли бы вы наконец найти причину? Я столкнулся с этой ошибкой сейчас   -  person Narges    schedule 20.09.2017
comment
Можете ли вы проверить, сколько подключений у вас доступно? Запустите это из оболочки mongo: db.serverStatus().connections {current: 204, available: 0, totalCreated: NumberLong (931)}   -  person Eric Clack    schedule 15.01.2018


Ответы (6)


Я согласен с ответом Рангауна, вот мое решение в коде 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;

}

Вот моя ссылка для исследования: http://3t.io/blog/how-to-prevent-your-connection-from-dropping-with-hosted-mongodb-instances/

Надеюсь, это поможет тебе.

person Daqian    schedule 16.09.2016
comment
Я использовал этот конструктор для создания соединения, но всегда получал исключение: MongoClient mongoClient = new MongoClient (new ServerAddress (203.11.83.230,27017), Arrays.asList (credential2)) Я перешел на другой с MongoClientOptions, все работает нормально для меня - person Daqian; 16.09.2016

Я нашел это в документации:

Для длительно работающих приложений часто целесообразно включить keepAlive с определенным количеством миллисекунд. Без него по прошествии некоторого времени вы можете начать видеть ошибки "соединение закрыто", хотя, кажется, без причины.

Проверьте, помогает ли это. Когда вы подключаетесь к mongoDB, вы можете передавать ему параметры сокета. Я из фона узла, мы используем следующие параметры, чтобы поддерживать его в рабочем состоянии.

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

Надеюсь это поможет!!

person Developer    schedule 07.09.2016
comment
Он устарел, так как теперь по умолчанию используется значение true. Поэтому он всегда включен: mongodb.github.io/mongo-java-driver/3.6/javadoc/com/mongodb/ - person streetturtle; 20.11.2019

Я решил эту проблему, установив для sslEnabled значение true, пример кода :

@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;
}

Дополнение: моя клиентская банка - это org.mongodb.mongodb-driver 3.6.4, сервер - mongodb atlas M0 3.6.6 на GCP.

person iengchen    schedule 25.07.2018
comment
если у вас был включен SSL, то где были сертификаты? и где находится код того же самого в приведенном выше фрагменте кода. - person Ankur Soni; 20.09.2018

Это сработало для меня при весенней загрузке и облачном монго (кластерные экземпляры Atlas).

Отредактируйте application.properties следующим образом:

spring.data.mongodb.uri = mongodb+srv://username:[email protected]/dbname

Для обычных экземпляров mongo (некластеризованных) используйте это:

spring.data.mongodb.uri = mongodb://username:[email protected]:27017,hostname2:27017/dbname?ssl=true
  • Если вы хотите установить другие параметры подключения, вы можете связать несколько параметров, используя '&'; документация здесь: https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClientURI.html.
  • Если вы использовали другие параметры spring.data.mongodb, вам следует удалить их все, иначе spring не будет читать spring.data.mongodb.uri
person jmojico    schedule 14.01.2019

Для меня это была совсем другая проблема - я использовал mongo-java-server с Fongo и в итоге получил эту ошибку. Оказывается, его старые версии несовместимы с FieldType.DECIMAL128 преобразованиями.

Обновление до последней версии (в настоящее время 1.36.0) устранило проблему для меня.

person maaw    schedule 13.10.2020

Проблема в том, что Mongodb завершает соединение. Вам нужно увеличить тайм-аут драйвера Mongodb, вот пример кода.

 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");
person Jose Salas    schedule 02.11.2020