Overview
Todos los drivers de MongoDB siguen un algoritmo definido al seleccionar un servidor para leer o guardar. Al usar la propiedad ClusterConfigurator de un objeto MongoClient, puedes personalizar este algoritmo para elegir el servidor que mejor funcione para tu aplicación.
Importante
Personalizar el algoritmo de selección del servidor podría tener consecuencias no previstas, como un rendimiento de lectura o escritura degradado.
Algoritmo por defecto
Cuando el controlador .NET/C# ejecuta una operación de lectura, realiza los siguientes pasos, en orden, para seleccionar una implementación de MongoDB:
Selecciona todos los servidores que coincidan con la preferencia de lectura activa de la lista de servidores conocidos.
Si existe al menos un servidor legible, el controlador llama a la función selector de servidores definida por el usuario y le pasa la lista del paso anterior.
Aplica la configuración de conexión
LocalThresholda la lista de servidores devuelta por la función.Selecciona un servidor al azar de la lista de servidores disponibles y ejecuta la operación en él.
Cuando el driver de .NET/C# ejecuta una operación de escritura, comienza seleccionando todos los servidores escribibles, no solo aquellos que coinciden con la preferencia de lectura activa. Los pasos restantes son idénticos.
Para obtener más información sobre el algoritmo de selección de servidor predeterminado, que el driver sigue cuando no especificas ninguna lógica de selección de servidor personalizada, consulta Algoritmo de selección de servidor en el manual de MongoDB Server.
Especificar otros algoritmos de selección de servidor
Se puede especificar una lógica diferente de selección de servidor pasando una instancia de una clase de selector de servidor a la propiedad PreServerSelector o PostServerSelector del ClusterConfigurator. La propiedad PreServerSelector es una propiedad que especifica un selector de servidor que se ejecuta antes de la lógica estándar de selección de servidor, mientras que la propiedad PostServerSelector es una propiedad que especifica un selector de servidor que se ejecuta después de que se ejecute la lógica estándar de selección de servidor. Luego, puedes pasar tu instancia de ClusterConfigurator al objeto MongoClientSettings cuando crees una instancia de MongoClient para aplicar tu lógica personalizada de selección de servidor.
La siguiente tabla enumera los diferentes tipos de selectores de servidor que puedes pasar a la propiedad ClusterConfigurator:
Selector de servidor | Descripción |
|---|---|
| Selecciona servidores basados en múltiples selectores parciales. |
| Envuelve un selector de servidor delegado |
| Selecciona los servidores en función de su endpoint |
| Selecciona servidores dentro de un rango de latencia aceptable |
| Selecciona un servidor en función de una colección de servidores para despriorizar |
| Selecciona un servidor aleatorio |
| Selecciona servidores según una preferencia de lectura especificada |
El siguiente ejemplo indica a un MongoClient que use la clase RandomServerSelector para seleccionar un servidor al azar antes de que se ejecute la lógica de selección de servidor estándar:
var settings = MongoClientSettings.FromConnectionString("<connection string>"); var clusterConfigurator = builder => { builder.ConfigureCluster(c => c.With(PreServerSelector: new RandomServerSelector())); }; settings.ClusterConfigurator = clusterConfigurator; var client = new MongoClient(settings);
Para obtener más información sobre las diferentes clases de selector de servidores, consulta la documentación de la API ServerSelectors.
Implementación de lógica personalizada de selección de servidores.
Puedes implementar tu propia lógica personalizada de selección de servidores creando una clase que herede de la interfaz IServerSelector y anule el método SelectServers(). El siguiente ejemplo muestra una clase simple de selección de servidores personalizada que selecciona servidores con un ServerType de ServerType.ReplicaSetSecondary:
public class CustomServerSelector : IServerSelector { public IEnumerable<ServerDescription> SelectServers(ClusterDescription cluster, IEnumerable<ServerDescription> servers) { return servers.Where(server => server.Type == ServerType.ReplicaSetSecondary); } }
A continuación, puedes pasar una instancia de esta clase a la propiedad PreServerSelector o PostServerSelector de una instancia de ClusterConfigurator, como se muestra en la sección Especificando Otros Algoritmos de Selección de Servidores.
Uso de Configuración para elegir el servidor
Puedes especificar las siguientes configuraciones de selección del servidor en tu objeto MongoClient o en tu URI de conexión:
Configuración | Descripción | |||
|---|---|---|---|---|
| La ventana de latencia para la elegibilidad del servidor. Si el tiempo de ida y vuelta de un servidor es más largo | |||
| La configuración de preferencia de lectura por defecto del cliente. | |||
| El tiempo que el driver intenta seleccionar un servidor antes de agotar el tiempo de espera. |
Solución de problemas
El driver arroja un tiempo de espera durante la selección del servidor
Cada operación del controlador requiere que elijas un servidor que cumpla con los criterios de selección de servidores. Si no selecciona un servidor apropiado dentro del límite de tiempo para selección de servidor, el driver lanza una excepción de límite de tiempo para selección de servidor. La excepción se parece a lo siguiente:
A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : "1", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", EndPoint: "Unspecified/localhost:27017", ReasonChanged: "Heartbeat", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", HeartbeatException: "<exception details>" }] }.
El mensaje de error consta de varias partes:
El tiempo de espera de selección del servidor (30000 ms).
Los selectores de servidor considerados (
CompositeServerSelectorque contienenAreSessionsSupportedServerSelector,LatencyLimitingServerSelector, yOperationsCountServerSelector).La vista actual del controlador de la topología del clúster. La lista de servidores de los que el controlador tiene conocimiento es un elemento clave de esta visión. Cada descripción del servidor contiene una descripción exhaustiva de su estado actual, incluida información sobre un endpoint, una versión de servidor, un tipo de servidor y su estado de salud actual. Si el servidor encuentra problemas en el reporte de su estado de salud,
HeartbeatExceptioncontiene la excepción del último fallo en el latido. Analizar elHeartbeatExceptionen cada nodo del clúster puede ayudar a diagnosticar la mayoría de los problemas de selección de servidores. Las siguientes excepciones del latido del corazón son comunes:No connection could be made because the target machine actively refused it: El driver no puede ver este nodo del clúster. Esto podría deberse a que el nodo del clúster ha fallado, que un firewall impide que el tráfico de red llegue al nodo o puerto del clúster, o a que otro error de red está evitando que el tráfico se enrute correctamente al nodo del clúster.Attempted to read past the end of the stream: Este error ocurre cuando el driver no puede conectarse a los nodos del clúster debido a un error de red, un firewall mal configurado u otro problema de red. Para solucionar esta excepción, asegúrese de que todos los nodos del clúster sean accesibles. Este error ocurre comúnmente cuando la dirección IP de la máquina cliente no está configurada en la lista de acceso IP de Atlas, que puede encontrar en la pestaña Network Access de su proyecto de Atlas.The remote certificate is invalid according to the validation procedureEste error suele indicar un problema relacionado con TLS/SSL, como un certificado expirado/no válido o una CA raíz no confiable. Puedes usar herramientas comoopenssl s_clientpara depurar problemas con certificados relacionados con TLS/SSL.
Documentación de la API
Para obtener más información sobre las clases y métodos utilizados en esta guía, consulta la siguiente documentación de la API: