gpt4 book ai didi

c# - 当主服务器出现故障时,有没有办法自动使 MongoDB C# 驱动程序不抛出 EndOfStreamException ?

转载 作者:IT老高 更新时间:2023-10-28 13:21:56 25 4
gpt4 key购买 nike

我一直在用 3 个实例的副本集测试官方 MongoDB C# 驱动程序。我创建了一个简单的应用程序,它可以循环访问副本集。

我的问题是:是否可以让 C# 驱动程序在我关闭主服务器时自动重新运行查询,而不像现在这样抛出 EndOfStreamException?

这是我的 MongoServerSettings 初始化代码:

        var settings = new MongoServerSettings()
{
ConnectionMode = ConnectionMode.ReplicaSet,
ReplicaSetName = "mongors",
ReadPreference = new ReadPreference(ReadPreferenceMode.PrimaryPreferred),
SafeMode = SafeMode.True,
DefaultCredentials = new MongoCredentials("user", "password"),
Servers = new[] { new MongoServerAddress("server.net", 27020),
new MongoServerAddress("server.net", 27019),
new MongoServerAddress("server.net", 27018)}

};

这是我查询服务器的代码:

        while (true)
{
var server = MongoServer.Create(settings);
var db = server.GetDatabase("db");
var collection = db.GetCollection<TaggedAction>("actions");
var query = Query.EQ("_id", id);
var entity = collection.FindOne(query);

Console.WriteLine(DateTime.Now +" " + entity.ActionName);

Thread.Sleep(2500);
}

如果我关闭主服务器,客户端会抛出以下异常:

System.IO.EndOfStreamException was unhandled
HResult=-2147024858
Message=Attempted to read past the end of the stream.
Source=MongoDB.Bson
StackTrace:
at MongoDB.Bson.IO.BsonBuffer.LoadFrom(Stream stream, Int32 count) in C:\work\rstam\mongo-csharp-driver\Bson\IO\BsonBuffer.cs: line 314
at MongoDB.Bson.IO.BsonBuffer.LoadFrom(Stream stream) in C:\work\rstam\mongo-csharp-driver\Bson\IO\BsonBuffer.cs: line 281
at MongoDB.Driver.Internal.MongoConnection.ReceiveMessage(BsonBinaryReaderSettings readerSettings, IBsonSerializationOptions serializationOptions) in C:\work\rstam\mongo-csharp-driver\Driver\Internal\MongoConnection.cs: line 478
at MongoDB.Driver.MongoCursorEnumerator`1.GetReply(MongoConnection connection, MongoRequestMessage message) in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs: line 296
at MongoDB.Driver.MongoCursorEnumerator`1.GetFirst() in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs: line 253
at MongoDB.Driver.MongoCursorEnumerator`1.MoveNext() in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs: line 141
at System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source)
at MongoDB.Driver.MongoCollection.FindOneAs(IMongoQuery query) in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCollection.cs: line 557
at MongoDB.Driver.MongoCollection`1.FindOne(IMongoQuery query) in C:\work\rstam\mongo-csharp-driver\Driver\Core\MongoCollection.cs: line 1734
at ConsoleApplication16.Program.Main(String[] args) in Program.cs: line 53
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

如果我只是吞下这个异常并继续循环,一切正常。因此它可以解决问题并切换到另一台服务器。但是,如果驱动程序可以自动处理这个问题,这样它就不会抛出异常,那就太好了。可能吗?

最佳答案

在许多情况下,无法进行故障转移,因为正在执行的游标只存在于主服务器上。辅助节点对此一无所知,因此无法继续。

在您的情况下,您碰巧知道您想继续,但我们会冒昧地满足您的需求并将其应用于所有情况。在你想继续循环的地方,其他人可能不会。

除此之外,某些驱动程序会重试查询。 .NET 驱动程序不会,因为我们觉得我们无法始终确定正确的行为,因此由应用程序决定。

在 PrimaryPreferred 的情况下,您希望读取来自 Primary 是有原因的 - 因为它们是最新的。如果我们默默地回退到辅助节点,那么根据辅助节点的回退距离,您的查询实际上有可能将最后一次成功查询之前的结果返回到主节点。这不是一个好的体验,因此我们根本不这样做,并建议您捕获这些错误并自己处理重试。

我们希望将其中一些错误包含在 MongoDB 特定异常中,这样您就不必猜测 EndOfStream 异常 (https://jira.mongodb.org/browse/CSHARP-474) 之类的事情。此外,如果您想查看此功能,请提交 jira,我们将研究如何以可预测的方式执行此操作 - 可能使用用户提供的策略来处理重试(IRetryStrategy 或其他东西)。

关于c# - 当主服务器出现故障时,有没有办法自动使 MongoDB C# 驱动程序不抛出 EndOfStreamException ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12761272/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com