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

本文关键字:多少 套接字 MongoClients 应用程序 C#2 驱动程序 Web 每个 MongoDB | 更新日期: 2023-09-27 18:10:45

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

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

我们的情况是,我们有两个不同的"集群"。

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

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

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

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

我预计驾驶员会以"最佳方式"处理秒数。

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

当然,每个API控制器调用都应该导致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)));
    }
};

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

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

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

  3. 每次你有一个叫做的Web API时,你应该打开一个新的连接

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

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

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

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

MongoDB文档的字面意思可能是"连接字符串",也就是说,只有字符串。

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

_client = new MongoClient("mongodb://localhost:27017");

但不是以下内容:

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

_client = new MongoClient(clientSettings);

即使您使用了来自singleton的相同MongoClientSettings对象,您仍然会得到不同的连接池。我也证实了这一点。

一个MongoClient实例并不意味着一个套接字,它内部有一个连接池,您可以控制池大小的最小值和最大值。最大池大小的默认值为100,这意味着它最多可以增长到100个打开的连接/套接字

根据文档,如何创建MongoClient并不重要,因为您最终应该有2个连接池,因为您有2个不同的连接字符串。但我会选择第2个,每个数据库一个MongoClient实例,因为无论技术如何,这都是所有mongo客户端的推荐方式

在您使用Postman运行测试的情况下,超时可能来自web服务器?mongodb.NET客户端的优点在于它公开了异步方法,因此您可以一直异步到webapi控制器。这将使您的web应用程序具有可扩展性,因为所有asp.net线程都将被重用,而不会在IO上被阻止。

您不应该担心混合套接字/连接,因为一个MongoClient并不意味着一个套接字。下面有许多正在使用的连接,它们只有在完成之前的工作时才能重复使用。如果你看一下csharp驱动程序的代码,你会发现它看起来很专业:(