AWS Lambda (Node.js, v. 8.10) & Mongoose:与数据库的 MongoNetworkError 连接超时
AWS Lambda (Node.js, v. 8.10) & Mongoose: MongoNetworkError connection to DB timed out
环境:
- AWS Lambda(Node.js,第 8.10 版),waitForEmptyEventLoop === false
- MongoDB(图集)
- 猫鼬
问题:有时(随机)出现下一个错误:
MongoNetworkError: connection 6 to db_host:27017 timed out
File "/opt/nodejs/node_modules/mongodb-core/lib/connection/connection.js", line 259, col 7, in TLSSocket.<anonymous>
new MongoNetworkError(f('connection %s to %s:%s timed out', self.id, self.host, self.port)),
File "events.js", line 313, col 30, in Object.onceWrapper
File "events.js", line 106, col 13, in emitNone
File "events.js", line 208, col 7, in TLSSocket.emit
File "net.js", line 420, col 8, in TLSSocket.Socket._onTimeout
File "timers.js", line 482, col 11, in ontimeout
File "timers.js", line 317, col 5, in tryOnTimeout
File "timers.js", line 277, col 5, in Timer.listOnTimeout
数据库连接代码:
const mongoose = require('mongoose');
const log = require('./log');
const options = {
reconnectTries: 30,
reconnectInterval: 500,
poolSize: Number(process.env.DB_POOLSIZE) || 1,
socketTimeoutMS: 30000,
keepAlive: true,
bufferCommands: false,
bufferMaxEntries: 0,
};
let isConnected;
module.exports.connect = () => new Promise((resolve, reject) => {
if (isConnected) {
return resolve();
}
return mongoose.connect(process.env.DB_URI, options)
.then((db) => {
isConnected = db.connections[0].readyState;
resolve();
}).catch((error) => {
log.error('DB:', error);
reject(error);
});
});
我检查过 - isConnected 缓存成功,mongodb 连接缓存在 mongoose 中。一切都必须没问题,但有时我会收到此错误。
有人知道我该如何解决这个问题吗?
您需要一个 'keep warm' script/functionality 来保持连接 alive/warm 通过不时查询。
此问题是由数据库连接超时或过期引起的,因为 Lambda 会在每次执行该函数时启动一个新的计算实例。它不会使现有连接保持温暖。
这是无服务器的一个已知问题,数据库连接持久性是间歇性的。
只需增加 socketTimeoutMS - 对我来说 2000000 足以在 "warm" 容器的 lambda 调用之间保持连接。
使用下一个配置(猫鼬):
{ reconnectTries: 30, reconnectInterval: 500, poolSize: 1, socketTimeoutMS: 2000000, keepAlive: true, }
另一个变体(smbd 将此视为最佳实践)- create/close 每个 lambda 调用的连接。如果您知道 lambda 很少会被调用,那不错的主意
环境:
- AWS Lambda(Node.js,第 8.10 版),waitForEmptyEventLoop === false
- MongoDB(图集)
- 猫鼬
问题:有时(随机)出现下一个错误:
MongoNetworkError: connection 6 to db_host:27017 timed out
File "/opt/nodejs/node_modules/mongodb-core/lib/connection/connection.js", line 259, col 7, in TLSSocket.<anonymous>
new MongoNetworkError(f('connection %s to %s:%s timed out', self.id, self.host, self.port)),
File "events.js", line 313, col 30, in Object.onceWrapper
File "events.js", line 106, col 13, in emitNone
File "events.js", line 208, col 7, in TLSSocket.emit
File "net.js", line 420, col 8, in TLSSocket.Socket._onTimeout
File "timers.js", line 482, col 11, in ontimeout
File "timers.js", line 317, col 5, in tryOnTimeout
File "timers.js", line 277, col 5, in Timer.listOnTimeout
数据库连接代码:
const mongoose = require('mongoose');
const log = require('./log');
const options = {
reconnectTries: 30,
reconnectInterval: 500,
poolSize: Number(process.env.DB_POOLSIZE) || 1,
socketTimeoutMS: 30000,
keepAlive: true,
bufferCommands: false,
bufferMaxEntries: 0,
};
let isConnected;
module.exports.connect = () => new Promise((resolve, reject) => {
if (isConnected) {
return resolve();
}
return mongoose.connect(process.env.DB_URI, options)
.then((db) => {
isConnected = db.connections[0].readyState;
resolve();
}).catch((error) => {
log.error('DB:', error);
reject(error);
});
});
我检查过 - isConnected 缓存成功,mongodb 连接缓存在 mongoose 中。一切都必须没问题,但有时我会收到此错误。
有人知道我该如何解决这个问题吗?
您需要一个 'keep warm' script/functionality 来保持连接 alive/warm 通过不时查询。
此问题是由数据库连接超时或过期引起的,因为 Lambda 会在每次执行该函数时启动一个新的计算实例。它不会使现有连接保持温暖。
这是无服务器的一个已知问题,数据库连接持久性是间歇性的。
只需增加 socketTimeoutMS - 对我来说 2000000 足以在 "warm" 容器的 lambda 调用之间保持连接。 使用下一个配置(猫鼬):
{ reconnectTries: 30, reconnectInterval: 500, poolSize: 1, socketTimeoutMS: 2000000, keepAlive: true, }
另一个变体(smbd 将此视为最佳实践)- create/close 每个 lambda 调用的连接。如果您知道 lambda 很少会被调用,那不错的主意