【问题标题】:MongoDB C# 2.0 TimeoutExceptionMongoDB C# 2.0 超时异常
【发布时间】:2015-07-02 04:19:40
【问题描述】:

我们最近将 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

我们正在使用一个单例 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);
}

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

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();
}

我们如何才能发现原因并解决此问题?

【问题讨论】:

  • 这需要更多的诊断。您可以在 jira.mongodb.org 的 CSHARP 项目下提交工单吗?我可以告诉你开始,异常告诉我们我们不再连接到服务器。发生了一些事情,导致我们失去了连接。所以,我想看到的一件事是来自服务器的日志(看起来好像你只有 1 个在独立模式下运行)。
  • 我每次在我的 ASP.NET MVC 应用程序中都得到相同的超时异常,但使用控制台应用程序中的相同库,我从来没有看到它。
  • 您知道如何解决您的错误吗?
  • 不 :( 我们已经回到 1.1 驱动程序。考虑在该功能的某个时候再试一次。
  • 这是很久以前的事了,但我在升级驱动程序后遇到了同样的问题。使用单例,问题只发生在负载下。 1.x 多年来没有问题,但 2.11 在峰值负载期间突然出现充满超时错误的日志(重试时通常会起作用)。

标签: mongodb-.net-driver timeoutexception mongodb-csharp-2.0


【解决方案1】:

这个post 可能会有所帮助:

我想通了。 This JIRA ticket有详细信息。

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

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

【讨论】:

  • 这是一个问题持续发生并且与 mongolab 相关的情况,因为 mongolab 将单个节点视为副本集。我们托管自己的 mongodb,而我们的问题是“不是连接到 mongodb”的问题,这是一个只有在重负载下才会出现的问题。
  • 这是为我解决的问题!谢谢!
【解决方案2】:

我在使用驱动程序 v2.2.4 时遇到了同样的问题。升级到v2.3.0后,问题好像已经解决了

【讨论】:

    【解决方案3】:

    此问题与 CSHARP-1435CSHARP-1515CSHARP-1538 错误报告有关,并且很可能已在最近的 C# MongoDB 驱动程序中修复。

    此问题可能与读取的文档数量超过一个批次返回的文档数量有关。source

    所以可能的解决方案是:

    • 确保您的 MongoDB 已启动并正在运行。source
    • 检查 MongoDB 日志以获取任何其他详细信息。
    • 如果连接到mongod 进程组(请参阅:replication),请将?connect=replicaSet 添加到您的连接字符串中。例如:

      mongodb://db1.example.net:27017,db2.example.net:2500/?replicaSet=test&connectTimeoutMS=300000
      

      示例ConnectionStrings.config 文件:

      <connectionStrings>
            <add name="MongoDB" connectionString="mongodb://10.0.80.231:27017,10.0.108.31:27017/?replicaSet=groupname&amp;connectTimeoutMS=600000&amp;socketTimeoutMS=600000" />
            <add name="RedisCache" connectionString="www-redis.foo.cache.amazonaws.com:6379" />
            <add name="SqlConnection" connectionString="server=api.foo.eu-west-1.rds.amazonaws.com;database=foo;uid=sqlvpc;pwd=somepass;" providerName="System.Data.SqlClient"  />
      </connectionStrings>
      

      相关:CSHARP-1160, How to include ampersand in connection string?

      如果上述方法不起作用,请检查:C# MongoDB Driver Ignores timeout options

    • 尝试按照上述错误报告升级MongoDB.Driver

    • 尝试增加连接和套接字超时。

      通过将?connectTimeoutMS=60000&amp;socketTimeoutMS=60000 附加到您的连接字符串。见:mongoDB Connection String Options

      或者更改代码中的设置(例如connecttimeoutmaxpoolsizewaitQueueSizewaitQueueTimeout)。请参阅example here

    • 检查连接字符串是否正确包含数据库。source
    • 在快速调用 MongoDB 的情况下增加每个查询之间的延迟。source

    请同时查看MongoDB Compatibility for MongoDB C#/.NET drivers:

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-12
        • 2018-11-22
        • 2017-04-19
        • 1970-01-01
        • 2017-07-02
        • 1970-01-01
        相关资源
        最近更新 更多