6

我們最近將我們的Web應用程序升級到MongoDB C#Driver 2.0並部署到生產環境。在一定的負載下,應用程序運行良好。一旦生產服務器上的負載超過一定限度時,應用程序的CPU瞬間下降到0,約30秒後,這個記錄異常幾次:MongoDB C#2.0 TimeoutException

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

我們怎樣才能找出原因和解決這個問題?

+3

這是要花費更多的診斷。你可以在jira.mongodb.org的CSHARP項目下申請一張票嗎? 我可以告訴你,從異常告訴我們,我們不再連接到服務器。發生了一些事情,導致我們失去連接。所以,我希望看到的一件事是來自服務器的日誌(它看起來好像你只有一個在獨立模式下運行)。 –

+0

我每次都在ASP.NET MVC應用程序中獲得相同的超時異常,但是從控制檯應用程序使用相同的庫,我從來沒有看到它。 –

+0

你知道如何解決你的錯誤嗎? – RPDeshaies

回答

0

我在MongoLab中使用免費(版本2.6)沙箱時遇到了同樣的問題,並且在開始使用付費羣集時超時問題消失了。

我想說的是,我認爲問題是隻支持MongoDB版本3.0+(因爲我發現一些文檔說的很多,我發誓我通過MongoLab 3.0升級過程),但是當我去搜索文檔,現在說2.6支持,我的付費MongoLab數據庫仍然說它是2.6.9版本。

我想我一定要瘋了,但至少我的代碼現在工作了!

4

post可能會有幫助:

我想通了。 This JIRA ticket有詳細信息。

實際上,我們已經取得了連接到 獨立的服務器,直接連接到副本集成員, 其中後者是比較少見的區別。不幸的是,MongoLab的 單節點設置實際上是一個單節點副本集,而這個 使我們不信任它。您可以通過將 ?connect=replicaSet附加到連接字符串來解決此問題。它將強制 驅動程序進入副本設置模式,並且所有操作都將起作用。因此,我們將重新考慮CSHARP-1160。非常感謝 報告,並讓我知道如果?connect=replicaSet附加到 您的連接字符串不起作用。

+0

這就是問題始終存在和相關的,因爲mongolab待到mongolab單節點作爲副本集的情況下,我們舉辦我們自己的MongoDB而我們的「不是連接到mongodb」的問題,這是一個只在重負載下才會出現的問題。 –

+0

這是爲我修復的!謝謝! –

2

我遇到了使用驅動程序v2.2.4的相同問題。升級到V2.3.0後,這個問題似乎已經解決

0

這個問題涉及到CSHARP-1435CSHARP-1515CSHARP-1538 bug報告,並極有可能這已被固定在最近的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-1160How to include ampersand in connection string?

    如果以上都不行,請檢查:C# MongoDB Driver Ignores timeout options

  • 嘗試升級MongoDB.Driver按照上面的錯誤報告。

  • 嘗試增加連接和套接字超時。

    無論是通過附加?connectTimeoutMS=60000&socketTimeoutMS=60000到連接字符串。參見:mongoDB Connection String Options

    或者更改代碼中的設置(例如connecttimeout,maxpoolsize,waitQueueSizewaitQueueTimeout)。請參閱example here

  • 檢查連接字符串是否正確包含數據庫。 source
  • 增加快速調用的MongoDB的情況下,每個查詢之間的延遲。 source

也請檢查MongoDB Compatibility for MongoDB C#/.NET drivers

C#/.NET Driver Version, MongoDB C#/.NET driver compatibility

相關問題