Client-Lebenszyklen in Java-Cloud-Clientbibliotheken verwalten

Clientbibliotheksinstanzen sind wiederverwendbar und für eine lange Lebensdauer konzipiert. In der Regel wird in Anwendungen eine einzelne Instanz einer Clientbibliothek verwaltet, anstatt für jede Anfrage eine Bibliothek zu erstellen.

Das folgende Snippet zeigt anhand von Java-KMS, wie mehrere Anfragen mit derselben Clientinstanz aufgerufen werden:

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

Kunden schließen

Wie Sie den Lebenszyklus eines Clients verwalten, kann vom Anwendungsfall und der jeweiligen Clientbibliothek abhängen. Wenn Sie beispielsweise ein Framework verwenden, folgen Sie den Richtlinien des Frameworks für die Clientverwaltung. In einigen Szenarien wird try-with-resources möglicherweise für kurzlebige Clients verwendet. Aus Effizienzgründen wird jedoch im Allgemeinen empfohlen, eine langlebige Clientinstanz wiederzuverwenden.

Wenn Sie close() für einen Client aufrufen, wird versucht, ihn ordnungsgemäß herunterzufahren. Außerdem wird dafür gesorgt, dass vorhandene Aufgaben bis zum Abschluss fortgesetzt werden. Der Client akzeptiert keine neuen Aufgaben. Wenn Sie den Client nicht schließen, bleiben seine Ressourcen erhalten und in Ihrer Anwendung treten Speicherlecks auf.

Im folgenden Beispiel wird Java-KMS verwendet und gezeigt, wie der Client geschlossen wird:

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

Zusätzlich zu close() stellen einige Java-Clientbibliotheken einige zugehörige Methoden zum Verwalten des Clientlebenszyklus bereit:

  • shutdown(): Entspricht close().
  • shutdownNow(): Ruft den Herunterfahrvorgang sofort auf. Beendet alle laufenden Aufgaben und wartet nicht, bis die Aufgabe abgeschlossen ist.
  • isShutdown(): Gibt true zurück, wenn die Hintergrundaufgaben beendet wurden.
  • isTerminated(): Gibt true zurück, wenn alle Aufgaben nach dem Herunterfahren abgeschlossen wurden.
  • awaitTermination(): Blockiert für einen Zeitraum, bis alle Arbeiten nach dem Herunterfahren abgeschlossen sind.

Vorgänge für mehrere Kunden

Es kann bestimmte Anwendungsfälle geben, die mehrere gleichzeitig vorhandene Instanzen einer Clientbibliothek erfordern. Der Hauptanwendungsfall für mehrere Clients ist, wenn Anfragen an mehrere verschiedene Endpunkte gesendet werden müssen. Eine Clientinstanz stellt eine Verbindung zu einem einzelnen Endpunkt her. Wenn Sie eine Verbindung zu mehreren Endpunkten herstellen möchten, erstellen Sie für jeden Endpunkt einen Client.

Potenzielle Risiken für mehrere Kunden

Bei Anwendungen, die mehrere Clientbibliotheksinstanzen verwenden, gibt es einige häufige Risiken:

  • Erhöhtes Potenzial für Arbeitsspeicherlecks: Ressourcen bleiben bestehen, wenn nicht alle Clientinstanzen ordnungsgemäß geschlossen werden.
  • Auswirkungen auf die Leistung: Das Initialisieren mehrerer gRPC-Kanäle verursacht Leistungskosten, die sich in leistungssensiblen Anwendungen summieren können.
  • Probleme mit aktiven Anfragen Wenn ein Client geschlossen wird, während Anfragen noch in Bearbeitung sind, kann dies zu einem RejectedExecutionException führen. Achten Sie darauf, dass Anfragen abgeschlossen werden, bevor der Client geschlossen wird.