javascript - Mongoose 超时与 AWS DocumentDB 交谈

标签 javascript mongoose serverless aws-documentdb

我们正在尝试在无服务器中基于 Express 构建的 lambda 中连接到 AWS DocumentDB。为此,我们使用 Mongoose 和一个看起来像的连接函数

import mongoose from 'mongoose';
import logger from './utils/logger';
import fs from 'fs';

const READYSTATE_CONNECTED = 1;

const mongoDB = process.env.MONGODB_URI;

const certificateFilePath = __dirname + '/rds-combined-ca-bundle.pem';
logger.info(`Loading certificate file from ${certificateFilePath}`);
let ca = [fs.readFileSync(certificateFilePath)];


logger.info('Connection is ' + mongoose.connection.readyState);
if (mongoose.connection.readyState !== READYSTATE_CONNECTED) {
    logger.info(`Connecting to mongo using env connection string ${mongoDB}`);
    mongoose.connect(mongoDB, { useNewUrlParser: true, useUnifiedTopology: true, checkServerIdentity: false, ssl: true, sslCA: ca }).catch((err) => {
        logger.error(`Unable to connect to mongoose due to ${err.reason}`);
        console.error(err);
    });
}
mongoose.Promise = global.Promise;
const db = mongoose.connection;

// eslint-disable-next-line no-console
db.on('error', console.error.bind(console, 'MongoDB connection error:'));

export default db;
这里的想法是我们维护一个连接并重用它,以避免为进入 lambda 的每个请求创建新连接的费用。在大多数情况下,这工作正常,但每隔一段时间(可能每天 2 次)我们就会看到连接到数据库的问题。它似乎使 lambda 崩溃得相当厉害,我们必须触发 lambda 上的更改以诱使 lambda 重新启动我们的应用程序,然后再过几个小时一切正常。我们在 4 个相同的环境中运行,似乎生产环境是唯一遇到此问题的环境。生产比其他环境稍微忙一些,但实际上只有 50%。
错误看起来像
2020-11-09T20:10:36.565Z d88c9b33-6b84-44cd-8c1d-297c6334aad5 ERROR MongooseServerSelectionError: connection timed out
at NativeConnection.Connection.openUri (/var/task/node_modules/mongoose/lib/connection.js:800:32)
at /var/task/node_modules/mongoose/lib/index.js:342:10
at /var/task/node_modules/mongoose/lib/helpers/promiseOrCallback.js:31:5
at new Promise (<anonymous>)
at promiseOrCallback (/var/task/node_modules/mongoose/lib/helpers/promiseOrCallback.js:30:10)
at Mongoose.connect (/var/task/node_modules/mongoose/lib/index.js:341:10)
at Object.<anonymous> (/var/task/src/mongoose.js:19:24)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14)
at Module.require (internal/modules/cjs/loader.js:1025:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (/var/task/src/AppBuilder.js:17:1)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10) {
reason: TopologyDescription {
type: 'ReplicaSetNoPrimary',
setName: 'rs0',
maxSetVersion: null,
maxElectionId: null,
servers: Map {
'documentdbmasterinstance-xxxx.xxx.us-east-1.docdb.amazonaws.com:27017' => [ServerDescription],
'documentdbreplica1instance-xxxx.xxxx.us-east-1.docdb.amazonaws.com:27017' => [ServerDescription],
'documentdbreplica2instance-xxxx.xxxx.us-east-1.docdb.amazonaws.com:27017' => [ServerDescription]
},
stale: false,
compatible: true,
compatibilityError: null,
logicalSessionTimeoutMinutes: null,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
commonWireVersion: 6
}
到目前为止,我们还无法确定导致这种情况的任何特定行为。当时与数据库的连接看起来确实略有增加,但只有大约 75 个连接,我们在 r5.large 上运行,它应该允许 1700 个连接,所以我们远远超出了这个限制。
我不确定是否提到了 ReplicaSetNoPrimary在错误日志中是一条红鲱鱼,但在类似的问题报告中似乎没有提到任何地方。我怀疑连接是否真的超时。所有 lambda 调用都不会超过 200 毫秒。
我想问题是:
  • 连接代码中是否有任何明显的东西会导致这种情况?
  • 有没有更好、更规范的方法来在这个由 lambda 转换的快速应用程序中建立和维护连接?
  • ReplicaSetNoPrimary表明 documentdb 选择新的主数据库或主数据库无法访问存在一些问题?
  • 关于更多日志记录的任何建议我可以添加以追逐这个吗?

  • 编辑:
    我们的连接字符串看起来像
    mongodb://redacted:redacted@prod-db.cluster-cvgzkbo26lzb.us-east-1.docdb.amazonaws.com:27017/database?ssl=true&ssl_ca_certs=rds-combined-ca-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
    

    最佳答案

    连接超时可能有多种原因。最常见的原因是将您的 IP 地址列入白名单或启用公共(public)访问权限,以便您可以访问数据库。
    另一个原因可能是您使用的协议(protocol)。有关更多信息,请分享连接字符串的格式,以便我可以相应地检查和更新我的答案。

    关于javascript - Mongoose 超时与 AWS DocumentDB 交谈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64760811/

    相关文章:

    mongodb - 查询不等于 null 或空的地方

    aws-lambda - 具有特定依赖项的无服务器部署 lambda@edge

    javascript - meteorjs Handlebars 自定义条件

    javascript - JS中替换字符串的一个字符

    Mongoose.js默认情况下来自查询结果的_id和__v除外

    node.js - Typescript & Mongoose - "this"在实例方法中不可用

    go - 如何在 Golang Cloud 函数中重用数据库连接?

    spring - Spring是否兼容无服务器计算

    javascript - Onsen 2.0 v 1.x - 纯 JS

    javascript - 为什么 Bootstrap 的 scrollspy 不起作用?