[node.js] mongoError : 토폴로지가 파괴되었습니다

Restify 및 Mongoose를 사용하여 node.js에 내장 된 REST 서비스와 약 30.000 개의 일반 크기 문서가있는 mongoDB가 있습니다. pmx와 pm2를 통해 노드 서비스를 실행하고 있습니다.

어제 갑자기 노드가 “MongoError : Topology was destroyed”메시지와 함께 오류를 크 래핑하기 시작했습니다. 나는 이것이 무엇을 의미하는지, 그리고 무엇이 이것을 유발할 수 있었는지 전혀 모른다. 구글 검색시 찾을 것도 많지 않습니다. 그래서 여기에 물어볼 줄 알았습니다.

오늘 노드 서비스를 다시 시작한 후 오류가 발생하는 것을 막았습니다. 나는 또한 프로덕션에서 이러한 중 하나를 실행하고 있으며 주어진 시간 에이 부분에서 실행되는 설정의 매우 중요한 부분에서 이것이 발생할 수 있다는 것을 두려워합니다 …

언급 된 패키지의 다음 버전을 사용하고 있습니다.

  • 몽구스 : 4.0.3
  • 재확인 : 3.0.3
  • 노드 : 0.10.25


답변

그것은 MongoDB 인스턴스에 대한 노드 서버의 연결이 중단되는 것을 의미합니다.

해당 오류를 생성하는 Mongo 소스 코드를 살펴보십시오.

Mongos.prototype.insert = function(ns, ops, options, callback) {
    if(typeof options == 'function') callback = options, options = {};
    if(this.s.state == DESTROYED) return callback(new MongoError(f('topology was destroyed')));
    // Topology is not connected, save the call in the provided store to be
    // Executed at some point when the handler deems it's reconnected
    if(!this.isConnected() && this.s.disconnectHandler != null) {
      callback = bindToCurrentDomain(callback);
      return this.s.disconnectHandler.add('insert', ns, ops, options, callback);
    }

    executeWriteOperation(this.s, 'insert', ns, ops, options, callback);
}

충돌이나 “수정”을 촉진하기 위해 업그레이드가 설치되지 않았기 때문에 주석에 인용 된 Sails 문제와 관련이없는 것으로 보입니다.


답변

Jason의 대답은 받아 들였지만 Mongoose와 같은 문제가 있었고 내 데이터베이스를 호스팅하는 서비스가 Mongodb의 연결을 프로덕션 환경 에서 유지하기 위해 다음 설정을 적용하는 것이 좋습니다 .

var options = {
  server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
  replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
};
mongoose.connect(secrets.db, options);

이 답변이 “Topology was destroyed”오류가있는 다른 사람들에게 도움이되기를 바랍니다.


답변

이 오류는 mongo 드라이버가 어떤 이유로 든 연결을 끊기 때문에 발생합니다 (예 : 서버가 다운 됨).

기본적으로 mongoose는 30 초 동안 다시 연결을 시도한 후 다시 시도를 중지하고 다시 시작할 때까지 영원히 오류를 발생시킵니다.

연결 옵션에서이 2 개의 필드를 편집하여이를 변경할 수 있습니다

mongoose.connect(uri,
    { server: {
        // sets how many times to try reconnecting
        reconnectTries: Number.MAX_VALUE,
        // sets the delay between every retry (milliseconds)
        reconnectInterval: 1000
        }
    }
);

연결 옵션 설명서


답변

필자의 경우이 오류는 db.close();‘비동기’내 ‘대기’섹션 이 부족하여 발생했습니다.

MongoClient.connect(url, {poolSize: 10, reconnectTries: Number.MAX_VALUE, reconnectInterval: 1000}, function(err, db) {
    // Validate the connection to Mongo
    assert.equal(null, err);
    // Query the SQL table 
    querySQL()
    .then(function (result) {
        console.log('Print results SQL');
        console.log(result);
        if(result.length > 0){

            processArray(db, result)
            .then(function (result) {
                console.log('Res');
                console.log(result);
            })
            .catch(function (err) {
                console.log('Err');
                console.log(err);
            })
        } else {
            console.log('Nothing to show in MySQL');
        }
    })
    .catch(function (err) {
        console.log(err);
    });
    db.close(); // <--------------------------------THIS LINE
});


답변

Gaafar의 대답에 사소한 추가 사항으로 인해 사용 중단 경고가 표시되었습니다. 서버 객체 대신 다음과 같이하십시오.

MongoClient.connect(MONGO_URL, {
    server: {
        reconnectTries: Number.MAX_VALUE,
        reconnectInterval: 1000
    }
});

최상위 개체로 이동할 수 있습니다. 기본적으로 서버 객체에서 꺼내어 다음과 같이 옵션 객체에 넣으십시오.

MongoClient.connect(MONGO_URL, {
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 1000
});


답변

이 주석에 따라 몽고 문서 색인을 작성하기 전에 몽구스 연결이 끊어져 “토폴로지가 손상되었습니다”가 발생할 수 있습니다 .

연결을 끊기 전에 모든 모델의 색인이 작성되도록하기 위해 다음을 수행 할 수 있습니다.

await Promise.all(mongoose.modelNames().map(model => mongoose.model(model).ensureIndexes()));

await mongoose.disconnect();


답변

Adrien의 답변에 대한 Sebastian의 의견은 더 많은 관심을 필요로하지만 도움이되는 의견은 언젠가 무시 될 수 있으므로 여기에 해결책이 있습니다 .

var options =  { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000 }
mongoose.connect(config.mongoConnectionString, options, (err) => {
    if(err) {
        console.error("Error while connecting", err);
    }
});