Java Cloud 클라이언트 라이브러리에서 클라이언트 수명 주기 관리

클라이언트 라이브러리 인스턴스는 재사용 가능하며 수명이 길도록 설계되었습니다. 일반적으로 애플리케이션은 각 요청에 라이브러리를 만드는 대신 클라이언트 라이브러리의 단일 인스턴스를 유지합니다.

Java-KMS를 예로 들어 다음 스니펫은 동일한 클라이언트 인스턴스로 호출되는 여러 요청을 보여줍니다.

// 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();

클라이언트 닫기

클라이언트의 수명 주기를 관리하는 방법은 사용 사례와 특정 클라이언트 라이브러리에 따라 다를 수 있습니다. 예를 들어 프레임워크를 사용하는 경우 클라이언트 관리에 관한 프레임워크의 가이드라인을 따르세요. 일부 시나리오에서는 수명이 짧은 클라이언트에 try-with-resources를 사용할 수 있지만 일반적으로 효율성을 위해 수명이 긴 클라이언트 인스턴스를 재사용하는 것이 좋습니다.

클라이언트에서 close()를 호출하면 순서대로 종료가 시도되고 기존 작업이 완료될 때까지 계속됩니다. 클라이언트는 새 작업을 수락하지 않습니다. 클라이언트를 닫지 않으면 리소스가 계속 유지되고 애플리케이션에 메모리 누수가 발생합니다.

다음 예에서는 Java-KMS를 사용하고 클라이언트가 닫히는 것을 보여줍니다.

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();

close() 외에도 일부 Java 클라이언트 라이브러리는 클라이언트 수명 주기를 관리하기 위한 몇 가지 관련 메서드를 노출합니다.

  • shutdown(): close()와 동일합니다.
  • shutdownNow(): 종료 프로세스를 즉시 호출합니다. 실행 중인 모든 작업을 중지하고 작업이 완료될 때까지 기다리지 않습니다.
  • isShutdown(): 백그라운드 작업이 종료된 경우 true를 반환합니다.
  • isTerminated(): 종료 후 모든 작업이 완료된 경우 true를 반환합니다.
  • awaitTermination(): 종료 후 모든 작업이 완료될 때까지 지정된 시간 동안 차단합니다.

여러 클라이언트의 사례

클라이언트 라이브러리의 여러 공존 인스턴스를 보증하는 특정 고객 사용 사례가 있을 수 있습니다. 여러 클라이언트를 사용하는 주요 사용 사례는 여러 다른 엔드포인트로 전송해야 하는 요청이 있는 경우입니다. 클라이언트 인스턴스는 단일 엔드포인트에 연결됩니다. 여러 엔드포인트에 연결하려면 각 엔드포인트에 클라이언트를 만드세요.

잠재적인 멀티 클라이언트 위험

여러 클라이언트 라이브러리 인스턴스를 사용하는 애플리케이션에는 몇 가지 일반적인 위험이 있습니다.

  • 메모리 누수 가능성 증가. 모든 클라이언트 인스턴스가 제대로 닫히지 않으면 리소스가 계속 유지됩니다.
  • 성능에 미치는 영향. 여러 gRPC 채널을 초기화하면 성능 비용이 발생하며, 이는 성능에 민감한 애플리케이션에서 누적될 수 있습니다.
  • 전송 중인 요청 관련 문제. 요청이 아직 전송 중인 동안 클라이언트를 닫으면 RejectedExecutionException이 발생할 수 있습니다. 클라이언트를 닫기 전에 요청이 완료되었는지 확인하세요.