MongoDB C#2.0 TimeoutException

Ser*_*gel 8 timeoutexception mongodb-csharp-2.0 mongodb-.net-driver

我们最近将我们的Web应用程序升级到MongoDB C#Driver 2.0并部署到生产中.低于一定负载,应用程序运行正常.一旦生产服务器上的负载超过某个限制,应用程序的CPU立即降至0,大约30秒后,将多次记录此异常:

System.TimeoutException message: A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{ ReadPreference = { Mode = Primary, TagSets = System.Collections.Generic.List`1[MongoDB.Driver.TagSet] } }, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", Type : "Standalone", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/10.4.0.113:27017" }", EndPoint: "Unspecified/10.4.0.113:27017", State: "Disconnected", Type: "Unknown" }] }.
stack trace:
at MongoDB.Driver.Core.Clusters.Cluster.ThrowTimeoutException(IServerSelector selector, ClusterDescription description)
at MongoDB.Driver.Core.Clusters.Cluster.<WaitForDescriptionChangedAsync>d__18.MoveNext()
--- End of stack trace
Run Code Online (Sandbox Code Playgroud)

我们正在使用单个MongoClient对象,它是这样启动的:

private static object _syncRoot = new object();

private static MongoClient _client;
private static IMongoDatabase _database;

private IMongoDatabase GetDatabase()
{
    ...

    if (_client == null)
    {
        lock (_syncRoot)
        {
            if (_client == null)
            {
                _client = new MongoClient(
                    new MongoClientSettings
                    {
                        Server = new MongoServerAddress(host, port),
                        Credentials = new[] { credentials },
                    });

                _database = _client.GetDatabase("proddb");
                return _database;
            }
        }
    }
    return _database;
}

public IMongoCollection<T> GetCollection<T>(string name)
{
    return GetDatabase().GetCollection<T>(name);
}
Run Code Online (Sandbox Code Playgroud)

对数据库的典型调用如下所示:

public async Task<MongoItem> GetById(string id)
{
    var collection = _connectionManager.GetCollection<MongoItem>("items");
    var fdb = new FilterDefinitionBuilder<MongoItem>();
    var f = fdb.Eq(mi => mi.Id, id);
    return await collection.Find(f).FirstOrDefaultAsync();
}
Run Code Online (Sandbox Code Playgroud)

我们如何发现原因并解决这个问题?

Daf*_*fan 6

这篇文章可能有所帮助

我想到了.这张JIRA门票有详细信息.

实际上,我们在连接到独立服务器和直接连接到副本集成员之间做了区分,后者相对不常见.不幸的是,MongoLab的单节点设置实际上是单节点副本集,这使我们不相信它.您可以通过附加?connect=replicaSet到连接字符串来解决此问题 .它将强制驱动程序进入副本设置模式,一切都会正常工作.

鉴于此,我们将重新考虑CSHARP-1160.非常感谢您的报告,如果附加?connect=replicaSet到您的连接字符串不起作用,请告诉我.


Col*_*lin 0

当我在 MongoLab 中使用免费(版本 2.6)沙箱时,我遇到了同样的问题,当我开始使用付费集群时,超时问题就消失了。

我想说我认为问题是只支持 MongoDB 3.0+ 版本(因为我发现一些文档说了这么多,我发誓我通过 MongoLab 完成了 3.0 升级过程),但是当我去搜索文档中,它现在说支持 2.6,而我的付费 MongoLab DB 仍然说它是版本 2.6.9。

我想我一定是疯了,但至少我的代码现在可以工作了!