MongoDB C# 2.0 驱动程序:每个 Web 应用程序分别有多少个 MongoClients 套接字?

Mat*_*ost 1 c# sockets mongodb asp.net-web-api mongodb-.net-driver

通常,您只需为给定集群创建一个 MongoClient 实例并在您的应用程序中使用它。但是,当且仅当连接字符串相同时,创建多个 MongoClient 仍将共享相同的连接池。

来源:http : //mongodb.github.io/mongo-csharp-driver/2.0/getting_started/quick_tour/

我们的情况是我们有两个不同的“集群”。

我们不使用复制或分片,但我们有两个不同的数据库。

这意味着我们的一些 API 函数将从一个数据库中获取数据,而其他 API 函数从第二个数据库中获取数据。这是硬编码的。

我们在每个类中创建了一个 SelectDatabase 方法,然后使用给定的设置创建一个 MongoClient。

同一个类将始终访问同一个数据库。

我预计驱动程序会以“最佳方式”处理秒数。

但事实证明,每次我刷新浏览器时,都会完成一个新的 Web API 控制器调用,因此也是一个新的 SelectDatabase 调用。这导致每次都有一个新的套接字(用 TCPView 检查)。

所以当然每个 API Controller 调用都应该导致 SelectDatabase,但我认为每次都创建一个套接字是一种矫枉过正。

我们正在创建这样的新 MongoClients:

//Creating multiple MongoClients will, however, still share the same pool of connections 
//if and only if the connection strings are identical.          
MongoClientSettings clientSettings1 = new MongoClientSettings()
{
    Server = new MongoServerAddress(host, port),
    ClusterConfigurator = builder =>
    {
        builder.ConfigureCluster(settings => settings.With(serverSelectionTimeout: TimeSpan.FromSeconds(serverSelectionTimeoutInSeconds)));
    }
};
Run Code Online (Sandbox Code Playgroud)

在我们的项目情况下,同时打开的套接字(Web 应用程序和数据库之间)和 MongoClient 实例的最佳数量是多少?

  1. Web 浏览器“套接字”生命周期应该只导致 Web 应用程序创建 1 个到数据库的套接字

  2. Web 应用程序应该只使用一个套接字,每个套接字每个数据库,完全独立于 Web 应用程序打开的 Web 浏览器或套接字的数量。

  3. 每次进行 Web API 调用时都应该打开一个新连接

我运行了一些 Postman 测试,在那里我创建了几百个 API 调用,我看到它分别用完了资源进入超时。当我选择方法 2 而不是 3 时,我看到它运行得更好。但是我担心 Web API 被频繁调用时创建的不同任务可能会以某种方式干扰然后在 Socket 级别上发生错误。

更新 我做了两个测试:第一个是基于每个请求都会生成一个新的 MongoClient 的原则。TCPView 向我展示了每个请求都会打开一个新的套接字。第二个测试是使用单例模式,它允许我每次访问相同的两个 MongoClient。第二个测试只使用了两个插座。我还需要说我更改了异步调用,以便方法在返回之前被阻塞(为简单起见,我不希望每个方法中都有这些 Task 返回类型)。

asz*_*ran 6

我做了一些试验,结果证明,如果您使用 MongoClientSettings 对象,即使连接字符串参数(主机、端口)相同,创建多个 MongoClient 也不会共享相同的连接池。

MongoDB 文档的字面意思可能是“连接字符串”,即只有字符串。

简而言之,以下工作按预期工作:

_client = new MongoClient("mongodb://localhost:27017");
Run Code Online (Sandbox Code Playgroud)

但不是以下:

MongoClientSettings clientSettings = new MongoClientSettings()
{
    Server = new MongoServerAddress(host, port),
    ClusterConfigurator = builder =>
    {
        builder.ConfigureCluster(settings => settings.With(serverSelectionTimeout: TimeSpan.FromSeconds(serverSelectionTimeoutInSeconds)));
    }
};


_client = new MongoClient(clientSettings);
Run Code Online (Sandbox Code Playgroud)

即使您从单例中使用了完全相同的 MongoClientSettings 对象,您仍然会获得不同的连接池。我也验证过。