programing

MongoSocketReadException: 스트림 끝에 너무 일찍 도달했습니다(일정 기간 동안 사용하지 않은 후).

minimums 2023. 6. 22. 21:38
반응형

MongoSocketReadException: 스트림 끝에 너무 일찍 도달했습니다(일정 기간 동안 사용하지 않은 후).

이 오류가 발생했습니다.find일정 기간 동안 사용하지 않으면 호출(기본 Java 드라이버)합니다.수동 하트비트(캡이 있는 컬렉션에 쓰기)를 추가하려고 했지만 도움이 되지 않았습니다.구성 시 인스턴스에 연결되어 있을 때만 문제가 발생합니다(즉, 로컬 컨텍스트에서는 그렇지 않음).

MongoDB 버전은 Java 8을 사용하는 최신 드라이버(3.3)인 3.2.8입니다.

감 잡히는 게 없어요?

문서에서 발견했습니다.

장시간 실행 중인 애플리케이션의 경우 몇 밀리초 단위로 "keepAlive"를 활성화하는 것이 좋습니다.그렇지 않으면 일정 시간이 지나면 이유가 없는 것처럼 보이는 "연결이 닫힘" 오류가 나타나기 시작할 수 있습니다.

이게 도움이 되는지 확인하세요.mongoDB에 연결할 때 소켓 옵션을 전달할 수 있습니다.저는 노드 배경에서 왔습니다. 우리는 노드를 활성화하기 위해 다음 옵션을 사용합니다.

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

이것이 도움이 되길 바랍니다!!

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

추가: 내 클라이언트 jar는 org.mongodb.mongodb-driver 3.6.4이고 서버는 GCP의 mongodb atlas M03.6.6입니다.

저는 여기서 Rangaun의 답변에 동의합니다. 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/

도움이 되길 바랍니다.

이것은 스프링 부트 및 클라우드 기반 mongo(Atlas 클러스터 인스턴스)에서 효과가 있었습니다.

다음과 같이 application.properties를 편집합니다.

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

일반 mongo 인스턴스(비클러스터)의 경우 다음을 사용합니다.

spring.data.mongodb.uri = mongodb://username:password@solarsystem-shard-00-00-1tpu0.mongodb.net: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를 읽을 수 없습니다.

저에게 그것은 완전히 다른 문제였습니다. 저는 퐁고와 함께 mongo-java-server를 사용하다가 결국 이 오류를 얻었습니다.이전 버전은 변환과 호환되지 않습니다.

최신 버전(현재 1.36.0)으로 업데이트하여 문제가 해결되었습니다.

문제는 Mongodb가 연결을 구부린다는 것입니다.Mongodb Driver의 시간 제한을 늘려야 합니다. 여기 예제 코드가 있습니다.

 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");

저는 두 단계를 밟은 후에 그것을 고칠 수 있었습니다.

번째 째번첫:
Mongo 클라이언트에 대한 키 설정을 포함하는 적절한 MongoClientSettings 개체 준비.

private MongoClientSettings getMongoClientSettings() {
    return MongoClientSettings.builder()
        .retryWrites(true)
        .applyToConnectionPoolSettings(poolSettings -> poolSettings
                .minSize(5)
                .maxSize(300)
                .maxConnectionIdleTime(0, TimeUnit.MILLISECONDS))
        .applyToSocketSettings(socketSettings -> socketSettings
                .connectTimeout(1, TimeUnit.MINUTES)
                .readTimeout(1, TimeUnit.MINUTES))
        .build();
}

maxConnectionIdleTime – 연결을 사용하지 않을 수 있는 최대 시간입니다.0 값은 유휴 시간에 대한 제한이 없음을 나타냅니다.

maxSize - 허용되는 최대 연결 수입니다.이러한 연결은 유휴 상태일 때 풀에 유지됩니다.풀이 모두 사용되면 연결이 필요한 모든 작업이 사용 가능한 연결 대기를 차단합니다.기본값은 100입니다.

minSize - 최소 연결 수입니다.이러한 연결은 유휴 상태일 때 풀에 유지되며, 풀에 이 최소 개수 이상이 포함되어 있는지 확인합니다.기본값은 0입니다.

번째 번째두:
/의 기본 초과 .properties / application.yaml 파일(이미 있는 파일)의 기본 시간 초과

mongodb:
 database: your_db_name
 authDatabase: admin
 config:
   enabled: true
   write:
     writeConcern:
       isMajority: true
     timeout:
       milliseconds: 100000

확인해보면 효과가 있을거에요 :)

언급URL : https://stackoverflow.com/questions/39079876/mongosocketreadexception-prematurely-reached-end-of-stream-after-a-period-of-i

반응형