Overview
Todos los drivers de MongoDB siguen un algoritmo definido al seleccionar un servidor del cual leer o al que guardar. Mediante el uso del ClusterConfigurator propiedad de un objeto MongoClient, puedes personalizar este algoritmo para elegir el servidor que funcione mejor 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 aprender más sobre el algoritmo de selección de servidores predeterminado, que el driver sigue cuando no especificas ninguna lógica de selección de servidores personalizada, consulta Algoritmo de selección de servidor en el manual del 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 | |||
|---|---|---|---|---|
| The latency window for server eligibility. If a server's round trip takes longer than the fastest server's round-trip time plus this value, the server isn't eligible for selection. Data Type: TimeSpanDefault: 15 milliseconds Connection URI Example: localThresholdMS=0 | |||
| The client's default read-preference settings. MaxStaleness represents thelongest replication lag (in real time) that a secondary can experience and still be eligible for server selection. Specifying -1 means no maximum.See read preference for more information. Data Type: ReadPreference Default: ReadPreference.PrimaryConnection URI Example: | |||
| The length of time the driver tries to select a server before timing out. Data Type: TimeSpanDefault: 30 seconds Connection URI Example: serverSelectionTimeoutMS=15000 |
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 streamEste error ocurre cuando el driver no puede conectarse a los nodos del clúster debido a un error de red, una configuración incorrecta del firewall u otro problema de red. Para resolver esta excepción, asegúrese de que todos los nodos del clúster sean accesibles. Este error comúnmente ocurre cuando la dirección IP de la máquina cliente no está configurada en la lista de acceso IP de Atlas, la cual se puede encontrar bajo la Network Access pestaña para tu Proyecto 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: