服务器上的活动连接数达到最大值
Number of active connections on the server reached to max
我正在使用 mongodb 和 nodejs。我在 Atlas 上托管了 mongodb。
我的后端一直运行良好,但现在有时会卡住,当我在 mongodb atlas 上看到分析时,它显示最大活动连接数达到 100.
有人可以解释为什么会这样吗?我可以重新启动连接并使其成为 0?
@Stennie 我用过 mongoose 连接数据库
这是我的配置文件
const mongooseOptions = {
useNewUrlParser: true,
autoReconnect: true,
poolSize: 25,
connectTimeoutMS: 30000,
socketTimeoutMS: 30000
}
exports.register = (server, options, next) => {
defaults = Hoek.applyToDefaults(defaults, options)
if (Mongoose.connection.readyState) {
return next()
}
if (!Mongoose.connection.readyState) {
server.log(`${process.env.NOED_ENV} server connecting to ${defaults.url} ${defaults.url}`)
return Mongoose.connect(defaults.url, mongooseOptions).then(() => {
return next() // call the next item in hapi bootstrap
})
}
}
假设您的后端部署在 lambda 上,因为无服务器标记。
每次调用都会让容器闲置以防止冷启动,或者使用现有容器(如果可用)。您正在打开连接以在调用之间重用它,如 best practices.
中所宣传的那样
poolSize
为 25 (?) 且最大连接数为 100,您应该将 function concurrency 限制为 4。
Reserve concurrency to prevent your function from using all the available concurrency in the region, or from overloading downstream resources.
更多阅读:https://www.mongodb.com/blog/post/optimizing-aws-lambda-performance-with-mongodb-atlas-and-nodejs
您可以尝试几件事:
在 serverless
环境中,正如@Gabriel Bleu 已经建议的那样,为什么会有这么高的 connectionLimit
。 Serverless
环境不断生成新容器并根据请求停止。如果同时产生多个实例,它会很快耗尽 MongoDB 服务器限制。
connectionPool
的概念是,x
每次从每个节点(实例)建立连接数。但这并不意味着所有连接在查询后都会自动释放。完成ALL DB操作后,应该release
每个连接个体使用后:mongoose.connection.close();
注意:Mongoose connection close会关闭连接池的所有连接。所以理想情况下,这应该是 运行 就在返回响应之前。
为什么要将显式 autoReconnect
设置为 true。 MongoDB driver internally 会在连接丢失时重新连接,当然不建议用于 serverless containers
.
等短寿命实例
如果您 运行 处于 cluster
模式,为了优化性能,将 serverUri
更改为副本集 URL 格式:MONGODB_URI=mongodb://<username>:<password>@<hostOne>,<hostTwo>,<hostThree>...&ssl=true&authSource=admin
.
影响max connection limit
的因素太多了。您有 mongoDB
托管在 Atlas 上,正如您提到的后端 lamda
意味着您有一个无服务器环境。
- 无服务器环境在新连接上生成新容器,并在不再使用时销毁连接。
peak
连接显示有太多新实例正在初始化或来自用户连接的并发请求太多。最佳做法是在不再需要时终止数据库连接。您可以终止连接
mongoose.connection.close();
因为你用过 mongoose
。它将从连接池中释放连接。与其耗尽并发连接限制,不如在连接空闲时释放连接。
- 您的配置强制数据库驱动程序在连接被数据库删除后重新连接。您显式地将
autoReconnect
设置为 true
,这样驱动程序将在连接断开后快速实例化连接请求。这可能会影响 concurrent connection limit
。您应该避免明确设置它。
cluster mode
可以根据负载优化请求,可以将服务器uri改为数据库副本。它可能有助于迁移负载。
- 首次调用 Lambda 函数并且 AWS Lambda 函数中的 MongoDB 客户端连接到 MongoDB 时,初始启动成本很小,大约需要 5 到 10 秒。连接到分片集群的
mongos
比连接到副本集更快。在 Lambda 函数的生命周期期间,后续连接将显着加快。所以每次调用都会让容器空闲以防止 cold start
或 cold boot
,或者使用现有容器(如果可用)。
- Atlas 根据集群层设置集群的并发传入连接限制。如果您在达到此限制时尝试连接,MongoDB 会显示一条错误消息“连接被拒绝,因为打开的连接太多”。您可以关闭当前未使用的与集群的任何打开连接。向下扩展到更高层以支持更多并发连接。如最佳实践中所述,您可以
restart
该应用程序。为防止将来出现此问题,请考虑使用 maxPoolSize 连接字符串选项来限制连接池中的连接数。
- 此问题的最终解决方案是升级到更大的 Atlas 集群层,从而允许更多连接。如果您的用户群对于您当前的集群层来说太大了。
我正在使用 mongodb 和 nodejs。我在 Atlas 上托管了 mongodb。
我的后端一直运行良好,但现在有时会卡住,当我在 mongodb atlas 上看到分析时,它显示最大活动连接数达到 100.
有人可以解释为什么会这样吗?我可以重新启动连接并使其成为 0?
@Stennie 我用过 mongoose 连接数据库
这是我的配置文件
const mongooseOptions = {
useNewUrlParser: true,
autoReconnect: true,
poolSize: 25,
connectTimeoutMS: 30000,
socketTimeoutMS: 30000
}
exports.register = (server, options, next) => {
defaults = Hoek.applyToDefaults(defaults, options)
if (Mongoose.connection.readyState) {
return next()
}
if (!Mongoose.connection.readyState) {
server.log(`${process.env.NOED_ENV} server connecting to ${defaults.url} ${defaults.url}`)
return Mongoose.connect(defaults.url, mongooseOptions).then(() => {
return next() // call the next item in hapi bootstrap
})
}
}
假设您的后端部署在 lambda 上,因为无服务器标记。
每次调用都会让容器闲置以防止冷启动,或者使用现有容器(如果可用)。您正在打开连接以在调用之间重用它,如 best practices.
中所宣传的那样poolSize
为 25 (?) 且最大连接数为 100,您应该将 function concurrency 限制为 4。
Reserve concurrency to prevent your function from using all the available concurrency in the region, or from overloading downstream resources.
更多阅读:https://www.mongodb.com/blog/post/optimizing-aws-lambda-performance-with-mongodb-atlas-and-nodejs
您可以尝试几件事:
在
serverless
环境中,正如@Gabriel Bleu 已经建议的那样,为什么会有这么高的connectionLimit
。Serverless
环境不断生成新容器并根据请求停止。如果同时产生多个实例,它会很快耗尽 MongoDB 服务器限制。connectionPool
的概念是,x
每次从每个节点(实例)建立连接数。但这并不意味着所有连接在查询后都会自动释放。完成ALL DB操作后,应该release
每个连接个体使用后:mongoose.connection.close();
注意:Mongoose connection close会关闭连接池的所有连接。所以理想情况下,这应该是 运行 就在返回响应之前。
为什么要将显式
autoReconnect
设置为 true。 MongoDB driver internally 会在连接丢失时重新连接,当然不建议用于serverless containers
. 等短寿命实例
如果您 运行 处于
cluster
模式,为了优化性能,将serverUri
更改为副本集 URL 格式:MONGODB_URI=mongodb://<username>:<password>@<hostOne>,<hostTwo>,<hostThree>...&ssl=true&authSource=admin
.
影响max connection limit
的因素太多了。您有 mongoDB
托管在 Atlas 上,正如您提到的后端 lamda
意味着您有一个无服务器环境。
- 无服务器环境在新连接上生成新容器,并在不再使用时销毁连接。
peak
连接显示有太多新实例正在初始化或来自用户连接的并发请求太多。最佳做法是在不再需要时终止数据库连接。您可以终止连接mongoose.connection.close();
因为你用过mongoose
。它将从连接池中释放连接。与其耗尽并发连接限制,不如在连接空闲时释放连接。 - 您的配置强制数据库驱动程序在连接被数据库删除后重新连接。您显式地将
autoReconnect
设置为true
,这样驱动程序将在连接断开后快速实例化连接请求。这可能会影响concurrent connection limit
。您应该避免明确设置它。 cluster mode
可以根据负载优化请求,可以将服务器uri改为数据库副本。它可能有助于迁移负载。- 首次调用 Lambda 函数并且 AWS Lambda 函数中的 MongoDB 客户端连接到 MongoDB 时,初始启动成本很小,大约需要 5 到 10 秒。连接到分片集群的
mongos
比连接到副本集更快。在 Lambda 函数的生命周期期间,后续连接将显着加快。所以每次调用都会让容器空闲以防止cold start
或cold boot
,或者使用现有容器(如果可用)。 - Atlas 根据集群层设置集群的并发传入连接限制。如果您在达到此限制时尝试连接,MongoDB 会显示一条错误消息“连接被拒绝,因为打开的连接太多”。您可以关闭当前未使用的与集群的任何打开连接。向下扩展到更高层以支持更多并发连接。如最佳实践中所述,您可以
restart
该应用程序。为防止将来出现此问题,请考虑使用 maxPoolSize 连接字符串选项来限制连接池中的连接数。 - 此问题的最终解决方案是升级到更大的 Atlas 集群层,从而允许更多连接。如果您的用户群对于您当前的集群层来说太大了。