多租户MongoDB + mongo-原生驱动+连接池

Multi-tenant MongoDB + mongo-native driver + connection pooling

我们正在尝试使用 nodejs/mongo-native 驱动程序实施以下演示文稿(幻灯片 13-18)中概述的策略。

https://www.slideshare.net/mongodb/securing-mongodb-to-serve-an-awsbased-multitenant-securityfanatic-saas-application

总结:

我能够使用 mongo-native 驱动程序创建到 mongodb 的连接池,而无需指定任何数据库,如下所示:

const client = new MongoClient('mongodb://localhost:27017', { useNewUrlParser: true, poolSize: 10 });

但是,为了得到一个数据库对象,我需要做以下事情:

const db = client.db(dbName);

这是我想验证连接的地方,它是 AFAICS,此功能已 deprecated/removed 来自更新的 mongo 驱动程序,node.js 和 java.

根据演示文稿,这似乎适用于旧版本的 Java 驱动程序。

我什至可以使用单个连接池并使用相同的连接向各个数据库验证租户吗?

我们的替代方案是每个租户都有一个连接池,目前这对我们没有吸引力。

我们将不胜感激任何帮助,包括此功能的原因 deprecated/removed。

幻灯片上的是我!! :) 我记得session,很有趣。

是的,这不再有效了,他们在我们实现它后大约 6 个月就取消了这个宏伟的功能,当时我们在 Beta 版中没有使用它。我们不得不改变我们的工作方式..

遗憾的是,直到今天,Mongo、"connection"(网络内容、SSL、集群标识)和身份验证是 2 个独立的操作。 想想当你 运行 mongo shell 时,你提供了主机、端口、副本集(如果有的话),以及你的 in,已连接!但未经认证。然后,您可以对 user1 进行身份验证,执行操作,然后对 user2 进行身份验证,并执行只有 user2 可以执行的操作。这是在同一个连接上完成的!无需通过开销再次创建通道、SSL 握手等...

那时,驱动程序让我们有一个包含 "blank" 个连接的连接池,我们可以在当前执行线程的上下文中随意对当前租户进行身份验证。

然后他们弃用了这个功能,我认为是 Mongo 2.4。现在他们只支持在创建时经过身份验证的连接。我们询问了企业支持,他们没有说明原因,但在我看来他们发现这种方式不安全,"old" 身份验证可能会泄漏,在 "not so blank" 可重用连接上徘徊。

我们对 multi-tenancy 基础设施实施进行了更改,从一个大的空白连接池到许多(小)经过身份验证的连接池,每个租户一个池。每个租户的这些池可能非常小,例如 3 或 5 个连接。这个解决方案很好地扩展到数百个租户,但为了满足数千个租户,我们必须进行各种优化以根据需要创建池、在空闲时间后关闭它们、为 non-active 或休眠租户延迟创建等。这使我们能够扩展更多...我们仍在研究解决方案和优化。

您始终可以返回到一个全局的经过身份验证的连接池,该连接池可以访问多个数据库的 Mongo 用户。是的,您可以在同一个经过身份验证的连接上切换数据库。你只是不能切换身份验证.. 这是一个纯 Mongo Java 驱动程序的示例,我们使用 Spring 提供类似的功能:

MongoClient mongoClient = new MongoClient();
DB cust1db = mongoClient.getDB("cust1");
cust1db.get...
DB cust2db = mongoClient.getDB("cust2");
cust2db.get...

有点相关,我建议查看 Mongo静态数据库加密,这是一项企业功能。唯一的方法是根据不同的密钥对每个数据库(每个客户)进行加密。