6

Abbiamo recentemente aggiornato la nostra applicazione Web a MongoDB C# Driver 2.0 e distribuita alla produzione. Sotto un certo carico, l'applicazione funziona correttamente. Quando il carico sul server di produzione supera un certo limite, la CPU dell'applicazione cade velocemente fino a 0 e dopo circa 30 secondi, questa eccezione viene registrato più volte: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 

Usiamo un oggetto MongoClient singoletto, che è iniziato in questo modo:

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

Una chiamata tipica a base di dati simile a questo:

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

Come possiamo scoprire il motivo e risolvere questo problema?

+3

questo sta andando a prendere molto di più diagnosi. Puoi presentare un ticket sotto il progetto CSHARP su jira.mongodb.org? Posso dirvi per iniziare che l'eccezione ci dice che non siamo più collegati al server. È successo qualcosa che ci ha fatto perdere la connettività. Quindi, una cosa che mi piacerebbe vedere sono i log dal server (sembra che tu abbia solo 1 in esecuzione in modalità standalone). –

+0

Ricevo sempre la stessa eccezione di timeout nell'app MV.NET di ASP.NET ma utilizzando la stessa libreria da un'app console, non la vedo mai. –

+0

Hai capito come correggere il tuo errore? – RPDeshaies

risposta

0

Ho avuto lo stesso problema quando utilizzavo la sandbox gratuita (versione 2.6) in MongoLab e il problema di timeout è andato via quando ho iniziato a utilizzare un cluster a pagamento.

Stavo per dire che pensavo che il problema fosse che solo la versione 3.0+ di MongoDB è supportata (perché ho trovato alcuni documenti che dicono tanto, e giuro di aver passato il processo di aggiornamento 3.0 via MongoLab), ma quando ho è andato a cercare la documentazione, ora dice che il 2.6 è supportato e il mio DB MongoLab pagato dice ancora che è la versione 2.6.9.

Penso che stia diventando pazzo, ma almeno il mio codice funziona ora!

4

Questo post può aiutare:

ho capito. This JIRA ticket ha i dettagli.

In effetti, abbiamo fatto una distinzione tra la connessione a un server standalone e la connessione diretta a un membro del set di repliche, dove quest'ultimo è relativamente raro. Sfortunatamente, le impostazioni di Single-Node di di MongoLab sono in realtà un set di repliche di un singolo nodo e questo ci obbliga a non fidarci di esso. È possibile risolvere questo problema aggiungendo ?connect=replicaSet alla stringa di connessione. Costringerà il driver a passare in modalità set di replica e tutto funzionerà.

Abbiamo intenzione di ri-considerare CSHARP-1160 alla luce di questo. Grazie mille per aver segnalato e fammi sapere se l'aggiunta di ?connect=replicaSet a la tua stringa di connessione non funziona.

+0

Questo è un caso in cui il problema si verifica in modo coerente e rilevante per mongolab poiché mongolab considera i singoli nodi come set di repliche. e il nostro è un problema di "non connettersi a mongodb", è un problema che si verifica solo sotto carico pesante –

+0

Questo è ciò che ha risolto per me! Grazie! –

2

Ho riscontrato lo stesso problema utilizzando il driver v2.2.4. Dopo l'aggiornamento a v2.3.0, il problema sembra essere stato risolto

0

Questo problema si riferisce a CSHARP-1435, CSHARP-1515 e CSHARP-1538 segnalazioni di bug, e molto probabilmente questo è stato risolto nel recente Driver C# MongoDB.

Questo problema potrebbe essere correlato alla lettura del numero di documenti restituiti più di un adattamento in un singolo batch.source

Quindi le soluzioni possibili sono:

  • Assicurarsi che il MongoDB è installato e funzionante. source
  • Controllare i registri MongoDB per ulteriori dettagli.
  • Se si esegue il collegamento a un gruppo di processi mongod (vedere: replication), aggiungere ?connect=replicaSet alla stringa di connessione. Per esempio:

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

    Esempio ConnectionStrings.config di file:

    <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> 
    

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

    Se in precedenza non funziona, controllare: C# MongoDB Driver Ignores timeout options.

  • Provare ad aggiornare MongoDB.Driver come da precedenti segnalazioni di bug.

  • Provare ad aumentare i timeout di connessione e socket.

    O aggiungendo ?connectTimeoutMS=60000&socketTimeoutMS=60000 alla stringa di connessione. Vedi: mongoDB Connection String Options.

    In alternativa modificare le impostazioni nel codice (ad esempio connecttimeout, maxpoolsize, waitQueueSize e waitQueueTimeout). Vedi lo example here.

  • Controllare la stringa di connessione se si include il database correttamente. source
  • Aumentare un ritardo tra ogni query in caso di chiamate rapide verso MongoDB. source

Si prega di verificare anche per MongoDB Compatibility for MongoDB C#/.NET drivers:

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

Problemi correlati