mongodb .net driver - MongoDB C#2.0 TimeoutException
mongodb-.net-driver mongodb-csharp-2.0 (4)
Recientemente hemos actualizado nuestra aplicación web a MongoDB C # Driver 2.0 y la hemos implementado en producción. Debajo de cierta carga, la aplicación funciona bien. Una vez que la carga en el servidor de producción excede un cierto límite, la CPU de la aplicación cae instantáneamente a 0 y después de aproximadamente 30 segundos, esta excepción se registra varias veces:
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
Estamos utilizando un objeto Singleton MongoClient, que se inicia así:
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 llamada típica a la base de datos se ve así:
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();
}
¿Cómo podemos descubrir la razón y solucionar este problema?
Esta post puede ayudar:
Me lo imaginé. Este boleto de JIRA tiene los detalles.
Efectivamente, hemos hecho una distinción entre conectarse a un servidor independiente y conectarse directamente a un miembro del conjunto de réplica, donde este último es relativamente poco común. Desafortunadamente, la configuración de un solo nodo de MongoLab es en realidad un conjunto de réplica de un solo nodo y esto hace que no confiemos en él. Puede solucionar esto agregando
?connect=replicaSet
a su cadena de conexión. Obligará al controlador a pasar al modo de configuración de réplica y todo funcionará.Vamos a reconsiderar CSHARP-1160 a la luz de esto. Muchas gracias por informar y avíseme si
?connect=replicaSet
a su cadena de conexión no funciona.
Estaba experimentando el mismo problema con el controlador v2.2.4. Después de actualizar a v2.3.0, el problema parece haberse resuelto
Este problema se relaciona con los CSHARP-1435 , CSHARP-1515 y CSHARP-1538 , y lo más probable es que esto se haya solucionado en el controlador C # MongoDB reciente.
Este problema podría estar relacionado con la lectura del número de documentos que se devuelven más de un ajuste en un solo lote. source
Entonces las posibles soluciones son:
- Asegúrese de que su MongoDB esté funcionando. source
- Consulte los registros de MongoDB para obtener detalles adicionales.
-
Si se conecta a un grupo de procesos
mongod
(ver: replication ), agregue?connect=replicaSet
a su cadena de conexión. Por ejemplo:mongodb://db1.example.net:27017,db2.example.net:2500/?replicaSet=test&connectTimeoutMS=300000
Ejemplo de archivo
ConnectionStrings.config
:<connectionStrings> <add name="MongoDB" connectionString="mongodb://10.0.80.231:27017,10.0.108.31:27017/?replicaSet=groupname&connectTimeoutMS=600000&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>
Relacionado: CSHARP-1160 , ¿Cómo incluir ampersand en la cadena de conexión?
Si lo anterior no funciona, verifique: C # MongoDB Driver Ignora las opciones de tiempo de espera .
-
Intente actualizar
MongoDB.Driver
según los informes de errores anteriores. -
Intente aumentar los tiempos de espera de conexión y socket.
Al
?connectTimeoutMS=60000&socketTimeoutMS=60000
a su cadena de conexión. Consulte: Opciones de cadena de conexión mongoDB .Alternativamente, cambie la configuración en su código (por ejemplo,
maxpoolsize
,waitQueueSize
,waitQueueSize
ywaitQueueTimeout
). Vea el ejemplo aquí . - Verifique la cadena de conexión si está incluyendo la base de datos correctamente. source
- Aumento de un retraso entre cada consulta en caso de llamadas rápidas a MongoDB. source
Compruebe también la compatibilidad de MongoDB para los controladores MongoDB C # /. NET :
Tuve este mismo problema cuando estaba usando el sandbox gratuito (versión 2.6) en MongoLab y el problema del tiempo de espera desapareció cuando comencé a usar un clúster pagado.
Iba a decir que pensé que el problema era que solo MongoDB versión 3.0+ es compatible (porque encontré algunos documentos que decían tanto, y juro que realicé el proceso de actualización 3.0 a través de MongoLab), pero cuando fui a buscar la documentación, ahora dice que 2.6 es compatible y mi MongoLab DB pagado todavía dice que es la versión 2.6.9.
Creo que debo volverme loco, ¡pero al menos mi código funciona ahora!