2016-09-29 20 views
16

UPDATE: Tôi đang sử dụng phiên bản 2.1 trên người lái xe, chống lại 3,2Đáng tin cậy kết nối lại với MongoDB

Tôi có một ứng dụng nút đó sử dụng MongoDB. Vấn đề tôi gặp phải là nếu máy chủ MongoDB bị hỏng vì bất kỳ lý do gì, ứng dụng sẽ không kết nối lại. Để có được quyền này, tôi dựa trên các thử nghiệm của tôi trên mã số trong this official tutorial.

var MongoClient = require('mongodb').MongoClient 
    , f = require('util').format; 

MongoClient.connect('mongodb://localhost:27017/test', 

// Optional: uncomment if necessary 
// { db: { bufferMaxEntries: 3 } }, 


function(err, db) { 
    var col = db.collection('t'); 

    setInterval(function() { 
    col.insert({a:1}, function(err, r) { 
     console.log("insert") 
     console.log(err) 

     col.findOne({}, function(err, doc) { 
     console.log("findOne") 
     console.log(err) 
     }); 
    }) 
    }, 1000) 
}); 

Ý tưởng là chạy tập lệnh này, sau đó dừng lại mong muốn, sau đó khởi động lại. Vì vậy, ở đây chúng tôi đi:

TEST 1: dừng mongod trong 10 giây

Dừng MongoDB trong 10 giây thì kết quả mong muốn: nó sẽ ngừng chạy các truy vấn đối với những 10 giây, và sau đó sẽ chạy tất cả họ một khi máy chủ đã trở lại ip

NGHIỆM 2: dừng mongod trong 30 giây

Sau đúng 30 giây, tôi bắt đầu nhận được:

{ [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' } 
insert 

{ [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' } 

Sự cố là từ lúc này, khi tôi khởi động lại mongod, kết nối không được tái xác định.

Giải pháp?

Vấn đề này có giải pháp không? Nếu vậy, bạn có biết nó là gì không? Khi ứng dụng của tôi bắt đầu nôn mửa "topo đã bị phá hủy", cách duy nhất để có được tất cả mọi thứ để làm việc một lần nữa là bằng cách khởi động lại toàn bộ ứng dụng ...

+0

Bạn có thể được tiếp cận vấn đề này từ sai hướng. Dựa trên chuỗi kết nối, ứng dụng của bạn đang kết nối với một cá thể nút duy nhất của cơ sở dữ liệu. Nếu cần thời gian cho ứng dụng của bạn, bạn nên cân nhắc kết nối với một bản sao được thiết lập với nhiều nút mang dữ liệu. Trình điều khiển, nếu được định cấu hình đúng cách, sẽ tự động kết nối lại với nút Chính mới sau khi chuyển đổi dự phòng. –

Trả lời

13

Có 2 tùy chọn kết nối mà kiểm soát cách Mongo nodejs lái xe kết nối lại sau khi kết nối thất bại

  • reconnectTries: cố gắng kết nối lại #times (mặc định là 30 lần)
  • reconnectInterval: server sẽ đợi # mili giây giữa retries (mặc định 1000 ms)

reference on mongo driver docs

Điều đó có nghĩa là mongo sẽ tiếp tục cố gắng kết nối 30 lần theo mặc định và chờ 1 giây trước mỗi lần thử lại. Đó là lý do tại sao bạn bắt đầu thấy lỗi sau 30 giây.

Bạn nên tinh chỉnh 2 thông số này dựa trên nhu cầu của bạn như mẫu này.

var MongoClient = require('mongodb').MongoClient, 
    f = require('util').format; 

MongoClient.connect('mongodb://localhost:27017/test', 
    { 
     // retry to connect for 60 times 
     reconnectTries: 60, 
     // wait 1 second before retrying 
     reconnectInterval: 1000 
    }, 

    function(err, db) { 
     var col = db.collection('t'); 

     setInterval(function() { 
      col.insert({ 
       a: 1 
      }, function(err, r) { 
       console.log("insert") 
       console.log(err) 

       col.findOne({}, function(err, doc) { 
        console.log("findOne") 
        console.log(err) 
       }); 
      }) 
     }, 1000) 
    }); 

Điều này sẽ thử 60 lần thay vì 30 mặc định, có nghĩa là bạn sẽ bắt đầu thấy lỗi sau 60 giây khi ngừng tìm cách kết nối lại.

Sidenote: nếu bạn muốn ngăn ứng dụng/yêu cầu chờ cho đến khi hết thời hạn kết nối, bạn phải chuyển tùy chọn bufferMaxEntries: 0. Giá cho điều này là yêu cầu cũng bị hủy trong thời gian gián đoạn mạng ngắn.

+0

Tôi đã cập nhật câu trả lời với phiên bản driver/mongo. Vẫn giống nhau? Tôi hỏi vì tài liệu "kết nối" không đề cập đến '{server: ...}': http://mongodb.github.io/node-mongodb-native/2.1/tutorials/connect/ Tuy nhiên, tài liệu cho "Cài đặt kết nối "(được liên kết từ liên kết này): http://mongodb.github.io/node-mongodb-native/2.1/reference/connecting/connection-settings/ không đề cập đến' {server: ...} ' ... – Merc

+0

Tôi đã thử nghiệm với các phiên bản tương tự và đối tượng tùy chọn dường như đang làm việc có hoặc không có 'server: {...}'. Tôi đoán nó có lý do di sản. Tôi đã xóa nó khỏi câu trả lời cho sự đơn giản. Hãy cho tôi biết nếu nó làm việc cho bạn. – Gaafar

+0

OH TÔI có ý định trả tiền thưởng cho câu trả lời này, và tôi vô tình trao nó cho người khác !!! – Merc

0

Hành vi có thể khác với các phiên bản trình điều khiển khác nhau. Bạn nên đề cập đến phiên bản trình điều khiển của bạn.

lái xe phiên bản: 2.2.10 (mới nhất) Mongo db phiên bản: 3.0.7

Dưới mã sẽ kéo dài thời gian mongod có thể làm để trở lại lên.

var MongoClient = require('mongodb').MongoClient 
    , f = require('util').format; 

function connectCallback(err, db) { 
    var col = db.collection('t'); 

    setInterval(function() { 
    col.insert({a:1}, function(err, r) { 
     console.log("insert") 
     console.log(err) 

     col.findOne({}, function(err, doc) { 
     console.log("findOne") 
     console.log(err) 
     }); 
    }) 
    }, 1000) 
} 
var options = { server: { reconnectTries: 2000,reconnectInterval: 1000 }} 
MongoClient.connect('mongodb://localhost:27017/test',options,connectCallback); 

Đối số thứ hai có thể được sử dụng để chuyển tùy chọn máy chủ.

+0

Tôi đã cập nhật câu trả lời với phiên bản driver/mongo. Vẫn giống nhau? – Merc

+0

Tôi hỏi vì tài liệu "kết nối" không đề cập đến '{server: ...}': http://mongodb.github.io/node-mongodb-native/2.1/tutorials/connect/ Tuy nhiên, tài liệu cho "Kết nối cài đặt "(được liên kết từ liên kết này): http://mongodb.github.io/node-mongodb-native/2.1/reference/connecting/connection-settings/ không đề cập đến' {server: ...} 'tại tất cả ... – Merc

+0

chỉnh sửa: trình điều khiển và phiên bản db. – inaitgaJ

4

Theo mặc định trình điều khiển Mongo sẽ cố gắng kết nối lại 30 lần, mỗi giây một lần. Sau đó nó sẽ không cố gắng kết nối lại.

Bạn có thể thiết lập số lần thử lại để Number.MAX_VALUE để giữ cho nó kết nối lại "gần như mãi mãi":

var connection = "mongodb://127.0.0.1:27017/db"; 
    MongoClient.connect(connection, { 
     server : { 
     reconnectTries : Number.MAX_VALUE, 
     autoReconnect : true 
     } 
    }, function (err, db) { 

    }); 
2

Nó đang xảy ra bởi vì nó có thể đã vượt quá giới hạn kết nối thử lại. Sau khi số lần thử lại, nó phá hủy kết nối TCP và không hoạt động. Vì vậy, để tăng số lần thử lại và sẽ tốt hơn nếu bạn tăng khoảng cách giữa kết nối lại.

Sử dụng bên dưới tùy chọn:

retryMiliSeconds {Number, default:5000}, number of milliseconds between retries. 
numberOfRetries {Number, default:5}, number of retries off connection. 

Để biết thêm thông tin chi tiết tham khảo liên kết này https://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html

Giải pháp:

MongoClient.connect("mongodb://localhost:27017/integration_test_?", { 
    db: { 
     native_parser: false, 
retryMiliSeconds: 100000, 
numberOfRetries: 100 
    }, 
    server: { 
     socketOptions: { 
     connectTimeoutMS: 500 
     } 
    } 
    }, callback) 
Các vấn đề liên quan