Las instancias de la biblioteca cliente son reutilizables y están diseñadas para durar mucho tiempo. Por lo general, las aplicaciones mantienen una sola instancia de una biblioteca cliente, en lugar de crear una biblioteca para cada solicitud.
Si usamos Java-KMS como ejemplo, el siguiente fragmento muestra varias solicitudes que se invocan con la misma instancia del cliente:
// Create one instance of KMS's KeyManagementServiceClient
KeyManagementServiceClient keyManagementServiceClient =
KeyManagementServiceClient.create();
keyManagementServiceClient.listKeyRings();
keyManagementServiceClient.asymmetricSign();
keyManagementServiceClient.createCryptoKey();
// ... other code ...
// Create one instance of KMS's AutokeyClient
AutokeyClient autokeyClient = AutokeyClient.create();
autokeyClient.listKeyHandles();
autokeyClient.getKeyHandle();
Cierra un cliente
La forma en que administras el ciclo de vida de un cliente puede depender del caso de uso y de la biblioteca cliente específica. Por ejemplo, si usas un framework, sigue los lineamientos del framework para la administración de clientes. Si bien algunos casos pueden usar try-with-resources para clientes de menor duración, por lo general, se recomienda reutilizar una instancia de cliente de larga duración para lograr eficiencia.
Si llamas a close() en un cliente, se intenta un cierre ordenado y se garantiza que las tareas existentes continúen hasta que se completen. El cliente no aceptará tareas nuevas. Si no cierras el cliente, sus recursos seguirán persistiendo y tu aplicación incurrirá en pérdidas de memoria.
En el siguiente ejemplo, se usa Java-KMS y se muestra el cierre del cliente:
KeyManagementServiceClient keyManagementServiceClient =
KeyManagementServiceClient.create(keyManagementServiceSettings);
// ... other code ...
keyManagementServiceClient.close();
// For gRPC clients, it's recommended to call awaitTermination to ensure a
// graceful shutdown and avoid the following error message in the logs:
// ERROR i.g.i.ManagedChannelOrphanWrapper - *~*~*~ Channel ManagedChannelImpl
// was not shutdown properly!!! ~*~*~*
// java.lang.RuntimeException: ManagedChannel allocation site
// at io.grpc.internal.ManagedChannelOrphanWrapper$ManagedChannelReference.<init>
keyManagementServiceClient.awaitTermination(DURATION, TimeUnit.SECONDS);
// Optionally include a shutdownNow() call after awaitTermination() to force
// close any lingering resources
keyManagementServiceClient.shutdownNow();
Además de close(), algunas bibliotecas cliente de Java exponen algunos métodos relacionados para administrar el ciclo de vida del cliente:
shutdown(): Es equivalente aclose().shutdownNow(): Invoca el proceso de cierre de inmediato. Detiene todas las tareas en ejecución y no espera a que se completen.isShutdown(): Muestratruesi se cerraron las tareas en segundo plano.isTerminated(): Muestratruesi se completaron todas las tareas después del cierre.awaitTermination(): Se bloquea durante un período hasta que se complete todo el trabajo después del cierre.
Casos para varios clientes
Puede haber casos de uso específicos de los clientes que justifiquen varias instancias coexistentes de una biblioteca cliente. El caso de uso principal para tener varios clientes es cuando hay solicitudes que se deben enviar a varios extremos diferentes. Una instancia de cliente se conecta a un solo extremo. Para conectarte a varios extremos, crea un cliente para cada uno.
Posibles riesgos de varios clientes
Existen algunos riesgos comunes con las aplicaciones que usan varias instancias de la biblioteca cliente:
- Mayor potencial de pérdidas de memoria. Los recursos permanecen si no se cierran correctamente todas las instancias del cliente.
- Implicaciones en el rendimiento. Inicializar varios canales de gRPC genera un costo de rendimiento, que puede acumularse en aplicaciones sensibles al rendimiento.
- Problemas con las solicitudes en curso. Cerrar un cliente mientras las solicitudes aún están en curso puede generar una
RejectedExecutionException. Asegúrate de que las solicitudes se completen antes de cerrar el cliente.