Gerenciar ciclos de vida de clientes nas bibliotecas de cliente do Cloud para Java

As instâncias de biblioteca de cliente são reutilizáveis e projetadas para durar muito tempo. Normalmente, os aplicativos mantêm uma única instância de uma biblioteca de cliente, em vez de criar uma biblioteca para cada solicitação.

Usando o Java-KMS como exemplo, o snippet a seguir mostra várias solicitações sendo invocadas com a mesma instância de 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();

Encerrar um cliente

A forma de gerenciar o ciclo de vida de um cliente depende do caso de uso e da biblioteca de cliente específica. Por exemplo, se você estiver usando um framework, siga as diretrizes dele para gerenciamento de clientes. Embora alguns cenários possam usar try-with-resources para clientes de curta duração, geralmente é recomendável reutilizar uma instância de cliente de longa duração para eficiência.

Chamar close() em um cliente tenta um desligamento ordenado e garante que as tarefas atuais continuem até a conclusão. O cliente não aceita novas tarefas. Se você não fechar o cliente, os recursos dele vão continuar persistindo, e seu aplicativo vai ter vazamentos de memória.

O exemplo a seguir usa o Java-KMS e mostra o fechamento do 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();

Além de close(), algumas bibliotecas de cliente Java expõem alguns métodos relacionados para gerenciar o ciclo de vida do cliente:

  • shutdown(): equivalente a close().
  • shutdownNow(): invoca o processo de desligamento imediatamente. Interrompe todas as tarefas em execução e não aguarda a conclusão.
  • isShutdown(): retorna true se as tarefas em segundo plano tiverem sido encerradas.
  • isTerminated(): retorna true se todas as tarefas forem concluídas após o desligamento.
  • awaitTermination(): bloqueia por um período até que todo o trabalho seja concluído após o desligamento.

Casos para vários clientes

Pode haver casos de uso específicos do cliente que justificam várias instâncias coexistentes de uma biblioteca de cliente. O principal caso de uso para ter vários clientes é quando há solicitações que precisam ser enviadas para vários endpoints diferentes. Uma instância de cliente se conecta a um único endpoint. Para se conectar a vários endpoints, crie um cliente para cada um deles.

Possíveis riscos para vários clientes

Há alguns riscos comuns em aplicativos que usam várias instâncias de biblioteca de cliente:

  • Aumento do potencial de vazamentos de memória. Os recursos permanecem se nem todas as instâncias de cliente forem fechadas corretamente.
  • Implicações no desempenho. Inicializar vários canais gRPC gera um custo de performance, que pode aumentar em aplicativos sensíveis à performance.
  • Problemas com solicitações em trânsito. Fechar um cliente enquanto as solicitações ainda estão em andamento pode resultar em um RejectedExecutionException. Verifique se as solicitações foram concluídas antes de fechar o cliente.