繁体   English   中英

如何检查与mongodb的连接

[英]How to check connection to mongodb

我使用MongoDB驱动程序连接到数据库。 当我的表单加载时,我想建立连接并检查它是否正常。 我这样做:

var connectionString = "mongodb://localhost";
var client = new MongoClient(connectionString);
var server = client.GetServer();
var database = server.GetDatabase("reestr");

但我不知道如何检查连接。 我尝试将此代码与try-catch重叠,但无济于事。 即使我创建了不正确的 connectionString,我仍然无法收到任何错误消息。

要使用新的 3.0 驱动程序 ping 服务器,请执行以下操作:

var database = client.GetDatabase("YourDbHere");

database.RunCommandAsync((Command<BsonDocument>)"{ping:1}")
        .Wait();

有一个ping 方法

var connectionString = "mongodb://localhost";
var client = new MongoClient(connectionString);
var server = client.GetServer();
server.Ping();

2.4.3 的完整示例 - 其中“client.GetServer()”不可用。 基于“保罗·凯斯特”的回答。

client = new MongoClient("mongodb://localhost");
database = client.GetDatabase(mongoDbStr);
bool isMongoLive = database.RunCommandAsync((Command<BsonDocument>)"{ping:1}").Wait(1000);

if(isMongoLive)
{
    // connected
}
else
{
    // couldn't connect
}

我和 OP 有同样的问题,并尝试了我能在互联网上找到的每一个解决方案......好吧,他们都没有让我真正满意,所以我选择了一项研究来找到一个可靠的以及检查与 MongoDB 数据库服务器的连接是否有效的响应方式。 这不会阻止应用程序的同步执行太长时间......

所以这是我的先决条件:

  • 连接检查的同步处理
  • 连接检查的短到非常短的时间片
  • 连接检查的可靠性
  • 如果可能,不抛出异常也不触发超时

我在默认的本地主机 URL 上提供了一个新的 MongoDB 安装(版本 3.6): mongodb://localhost:27017 我还写下了另一个没有 MongoDB 数据库服务器的 URL: mongodb://localhost:27071

我也在使用 C# 驱动程序 2.4.4 并且使用遗留实现(MongoDB.Driver.Legacy 程序集)。

所以我的期望是,当我检查到第一个 URL 的连接时,它应该给我 Ok 以确保与现有 MongoDB 服务器的活动连接,当我检查到第二个 URL 的连接时,它应该给我不存在的 MongoDB 服务器的失败...

使用 IMongoDatabase.RunCommand 方法查询服务器并导致服务器响应超时,因此不符合先决条件。 此外,超时后,它会因 TimeoutException 而中断,这需要额外的异常处理。

这个实际的 SO 问题以及这个SO 问题已经提供了我的解决方案所需的大部分启动信息......所以伙计们,非常感谢!

现在我的解决方案:

    private static bool ProbeForMongoDbConnection(string connectionString, string dbName)
    {
        var probeTask = 
                Task.Run(() =>
                            {
                                var isAlive = false;
                                var client = new MongoDB.Driver.MongoClient(connectionString);

                                for (var k = 0; k < 6; k++)
                                {
                                    client.GetDatabase(dbName);
                                    var server = client.Cluster.Description.Servers.FirstOrDefault();
                                    isAlive = (server != null && 
                                               server.HeartbeatException == null && 
                                               server.State == MongoDB.Driver.Core.Servers.ServerState.Connected);
                                    if (isAlive)
                                    {
                                        break;
                                    }
                                    System.Threading.Thread.Sleep(300);
                                }
                                return isAlive;
                            });
        probeTask.Wait();
        return probeTask.Result;
    }

这背后的想法是 MongoDB 服务器不会做出反应(并且似乎不存在),直到真正尝试访问服务器上的某些资源(例如数据库)。 但是仅仅检索一些资源是不够的,因为服务器仍然没有更新它在服务器集群描述中的状态。 当再次检索资源时,首先进行此更新。 从这个时间点开始,服务器有有效的集群描述和有效的数据......

一般来说,在我看来,MongoDB 服务器不会主动将其集群描述传播到所有连接的客户端。 相反,当向服务器发出请求时,每个客户端都会收到描述。 如果你们中的一些人有更多关于这方面的信息,请确认或否认我对这个话题的理解......

现在,当我们以无效的 MongoDB 服务器 URL 为目标时,集群描述仍然无效,我们可以捕获并为这种情况提供可用信号......

所以下面的语句(对于有效的 URL)

// The admin database should exist on each MongoDB 3.6 Installation, if not explicitly deleted!
var isAlive = ProbeForMongoDbConnection("mongodb://localhost:27017", "admin");
Console.WriteLine("Connection to mongodb://localhost:27017 was " + (isAlive ? "successful!" : "NOT successful!"));

会打印出来

连接到 mongodb://localhost:27017 成功!

和语句(对于无效的 URL)

// The admin database should exist on each MongoDB 3.6 Installation, if not explicitly deleted!
isAlive = ProbeForMongoDbConnection("mongodb://localhost:27071", "admin");
Console.WriteLine("Connection to mongodb://localhost:27071 was " + (isAlive ? "successful!" : "NOT successful!"));

会打印出来

连接到 mongodb://localhost:27071 没有成功!

这里有一个简单的扩展方法来ping mongodb 服务器

public static class MongoDbExt
{
    public static bool Ping(this IMongoDatabase db, int secondToWait = 1)
    {
        if (secondToWait <= 0)
            throw new ArgumentOutOfRangeException("secondToWait", secondToWait, "Must be at least 1 second");

        return db.RunCommandAsync((Command<MongoDB.Bson.BsonDocument>)"{ping:1}").Wait(secondToWait * 1000);
    }
} 

你可以像这样使用它:

var client = new MongoClient("yourConnectionString");
var database = client.GetDatabase("yourDatabase");
if (!database.Ping())
    throw new Exception("Could not connect to MongoDb");

这是使用 try-catch 方法的解决方案,

var database = client.GetDatabase("YourDbHere");
bool isMongoConnected;
try
{
     await database.RunCommandAsync((Command<BsonDocument>)"{ping:1}");
     isMongoConnected = true;
}
catch(Exception)
{
    isMongoConnected = false;
}    

所以当它无法连接到数据库时,它会抛出一个异常,我们可以在那里处理我们的 bool 标志。

如果要处理程序中的连接问题,可以使用ICluster.Description事件。

创建MongoClient ,它将在后台继续尝试连接,直到成功。

using MongoDB.Driver;
using MongoDB.Driver.Core.Clusters;

var mongoClient = new MongoClient("localhost")
mongoClient.Cluster.DescriptionChanged += Cluster_DescriptionChanged;

public void Cluster_DescriptionChanged(object sender, ClusterDescriptionChangedEventArgs e)
{
    switch (e.NewClusterDescription.State)
    {
        case ClusterState.Disconnected:
            break;
        case ClusterState.Connected:
            break;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM