HTTP-Clients und -Pipelines im Azure SDK für Java

Dieser Artikel bietet eine Übersicht über die HTTP-Client- und Pipelinefunktionen im Azure SDK für Java. Diese Funktionen bieten für Entwickler, die Azure SDK für Java-Bibliotheken verwenden, eine konsistente, leistungsstarke und flexible Benutzeroberfläche.

HTTP-Clients

Das Azure SDK für Java wird mithilfe einer HttpClient-Abstraktion implementiert. Diese Abstraktion ermöglicht eine austauschbare Architektur, die mehrere HTTP-Clientbibliotheken oder benutzerdefinierte Implementierungen akzeptiert. Um die Abhängigkeitsverwaltung jedoch für die meisten Benutzer zu vereinfachen, sind alle Azure-Clientbibliotheken von azure-core-http-netty abhängig. Daher ist der Netty-HTTP-Client der Standardclient, der in allen Azure SDK für Java-Bibliotheken verwendet wird.

Obwohl Netty der HTTP-Standardclient ist, stellt das SDK drei Clientimplementierungen abhängig davon bereit, welche Abhängigkeiten bereits in Ihrem Projekt vorhanden sind. Diese Implementierungen beziehen sich auf:

Hinweis

Das JDK HttpClient in Kombination mit dem Azure SDK für Java wird nur mit JDK 12 und höher unterstützt.

Ersetzen des HTTP-Standardclients

Wenn Sie eine andere Implementierung bevorzugen, können Sie die Abhängigkeit von Netty entfernen, indem Sie sie in den Buildkonfigurationsdateien ausschließen. In einer Maven-Datei pom.xml schließen Sie die Netty-Abhängigkeit aus und schließen eine andere Abhängigkeit ein.

Im folgenden Beispiel wird gezeigt, wie die Netty-Abhängigkeit aus einer realen Abhängigkeit von der azure-security-keyvault-secrets-Bibliothek ausgeschlossen wird. Stellen Sie sicher, dass Sie Netty aus allen entsprechenden com.azure-Bibliotheken ausschließen, wie hier gezeigt:

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-security-keyvault-secrets</artifactId>
    <version>4.2.2.</version>
    <exclusions>
      <exclusion>
        <groupId>com.azure</groupId>
        <artifactId>azure-core-http-netty</artifactId>
      </exclusion>
    </exclusions>
</dependency>

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-core-http-okhttp</artifactId>
  <version>1.3.3</version>
</dependency>

Hinweis

Wenn Sie die Netty-Abhängigkeit entfernen, aber keine Implementierung an ihrer Stelle bereitstellen, kann die Anwendung nicht gestartet werden. Eine HttpClient-Implementierung muss im Klassenpfad vorhanden sein.

Konfigurieren von HTTP-Clients

Wenn Sie einen Dienstclient erstellen, wird standardmäßig ein Dienstclient verwendet HttpClient.createDefault(). Diese Methode gibt basierend auf der bereitgestellten HTTP-Clientimplementierung eine grundlegende HttpClient-Instanz zurück. Wenn Sie einen komplexeren HTTP-Client benötigen (z. B. einen Proxy), bietet jede Implementierung einen Generator, mit dem Sie eine konfigurierte HttpClient-Instanz erstellen können. Die Generatoren sind NettyAsyncHttpClientBuilder, OkHttpAsyncHttpClientBuilder und JdkAsyncHttpClientBuilder.

In den folgenden Beispielen wird gezeigt, wie HttpClient-Instanzen mit Netty, OkHttp und dem JDK 11-HTTP-Client erstellt werden. Diese Instanzen verwenden als Proxy http://localhost:3128 und authentifizieren sich mit dem Benutzer example mit dem Kennwort weakPassword.

// Netty
HttpClient httpClient = new NettyAsyncHttpClientBuilder()
    .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
        .setCredentials("example", "weakPassword"))
    .build();

// OkHttp
HttpClient httpClient = new OkHttpAsyncHttpClientBuilder()
    .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
        .setCredentials("example", "weakPassword"))
    .build();

// JDK 11 HttpClient
HttpClient client = new JdkAsyncHttpClientBuilder()
    .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
        .setCredentials("example", "weakPassword"))
    .build();

Sie können jetzt die generierte HttpClient-Instanz an einen Dienstclient-Generator übergeben, damit sie als Client für die Kommunikation mit dem Dienst verwendet wird. Im folgenden Beispiel wird die neue HttpClient-Instanz verwendet, um einen Azure Storage Blob-Client zu erstellen.

BlobClient blobClient = new BlobClientBuilder()
    .connectionString(<connection string>)
    .containerName("container")
    .blobName("blob")
    .httpClient(httpClient)
    .build();

Für Verwaltungsbibliotheken können Sie den HttpClient während der Manager-Konfiguration festlegen.

AzureResourceManager azureResourceManager = AzureResourceManager.configure()
    .withHttpClient(httpClient)
    .authenticate(credential, profile)
    .withDefaultSubscription();

HTTP-Pipeline

Die HTTP-Pipeline ist eine der Hauptkomponenten zum Erreichen von Konsistenz und Diagnosefähigkeiten in den Java-Clientbibliotheken für Azure. Eine HTTP-Pipeline besteht aus den folgenden Komponenten:

  • Einem HTTP-Transport
  • HTTP-Pipelinerichtlinien

Sie können eine eigene benutzerdefinierte HTTP-Pipeline bereitstellen, wenn Sie einen Client erstellen. Wenn Sie keine Pipeline bereitstellen, erstellt die Clientbibliothek eine, die für die Arbeit mit dieser bestimmten Clientbibliothek konfiguriert ist.

HTTP-Transport

Der HTTP-Transport ist für das Herstellen der Verbindung mit dem Server und das Senden und Empfangen von HTTP-Nachrichten verantwortlich. Der HTTP-Transport bildet das Gateway für die Azure SDK-Clientbibliotheken für die Interaktion mit Azure-Diensten. Wie bereits weiter oben in diesem Artikel erwähntwurde, verwendet das Azure SDK für Java standardmäßig Netty für den HTTP-Transport. Das SDK stellt jedoch auch einen austauschbaren HTTP-Transport bereit, sodass Sie ggf. andere Implementierungen verwenden können. Das SDK bietet auch zwei weitere HTTP-Transportimplementierungen für OkHttp und den HTTP-Client, der im Lieferumfang von JDK 11 oder höher enthalten ist.

HTTP-Pipelinerichtlinien

Eine Pipeline besteht aus einer Abfolge von Schritten, die für jeden HTTP-Anforderung/Antwort-Roundtrip ausgeführt werden. Jede Richtlinie hat einen dedizierten Zweck und handelt auf anforderungs- oder antwort oder manchmal beides. Da alle Clientbibliotheken über eine standardmäßige Ebene „Azure Core“ verfügen, gewährleistet diese Ebene, dass jede Richtlinie in der Pipeline in der richtigen Reihenfolge ausgeführt wird. Wenn Sie eine Anforderung senden, werden die Richtlinien in der Reihenfolge ausgeführt, in der sie der Pipeline hinzugefügt wurden. Wenn Sie eine Antwort vom Dienst erhalten, werden die Richtlinien in umgekehrter Reihenfolge ausgeführt. Alle Richtlinien, die der Pipeline hinzugefügt werden, werden vor dem Senden der Anforderung und nach dem Empfangen einer Antwort ausgeführt. Die Richtlinie muss entscheiden, ob sie für die Anforderung, für die Antwort oder für beides eine Aktion ausführt. Beispielsweise protokolliert eine Protokollierungsrichtlinie die Anforderung und Antwort, aber die Authentifizierungsrichtlinie ist nur daran interessiert, die Anforderung zu ändern.

Das Azure Core-Framework stellt die Richtlinie zusammen mit jedem erforderlichen Kontext für die Ausführung der Richtlinie die erforderlichen Anforderungs- und Antwortdaten bereit. Die Richtlinie kann dann den Vorgang mit den angegebenen Daten ausführen und die Steuerung dann an die nächste Richtlinie in der Pipeline übergeben.

HTTP pipeline diagram

Position der HTTP-Pipelinerichtlinie

Wenn Sie HTTP-Anforderungen an Clouddienste senden, ist es wichtig, vorübergehende Fehler zu behandeln und fehlerhafte Versuche zu wiederholen. Da diese Funktion eine gängige Anforderung ist, stellt Azure Core eine Wiederholungsrichtlinie zur Verfügung, die auf vorübergehende Fehler achten und die Anforderung automatisch wiederholen kann.

Diese Wiederholungsrichtlinie teilt daher die gesamte Pipeline in zwei Teile auf: Richtlinien, die vor der Wiederholungsrichtlinie ausgeführt werden, und Richtlinien, die nach der Wiederholungsrichtlinie ausgeführt werden. Richtlinien, die vor der Wiederholungsrichtlinie hinzugefügt wurden, werden nur ein Mal pro API-Vorgang ausgeführt. Richtlinien, die nach der Wiederholungsrichtlinie hinzugefügt wurden, werden so oft wie die Wiederholungsversuche ausgeführt.

Wenn Sie die HTTP-Pipeline erstellen, sollten Sie also wissen, ob eine Richtlinie für jede Anforderungswiederholung oder ein Mal pro API-Vorgang ausgeführt werden soll.

Gängige HTTP-Pipelinerichtlinien

HTTP-Pipelines für REST-basierte Dienste verfügen über Konfigurationen mit Richtlinien für Authentifizierung, Wiederholungsversuche, Protokollierung, Telemetrie und die Angabe der Anforderungs-ID im Header. Azure Core wird mit diesen häufig erforderlichen HTTP-Richtlinien vorinstalliert, die Sie der Pipeline hinzufügen können.

Policy GitHub-Link
Wiederholungsrichtlinie RetryPolicy.java
Authentifizierungsrichtlinie BearerTokenAuthenticationPolicy.java
Protokollierungsrichtlinie HttpLoggingPolicy.java
Anforderungs-ID-Richtlinie RequestIdPolicy.java
Telemetrierichtlinie UserAgentPolicy.java

Benutzerdefinierte HTTP-Pipelinerichtlinie

Die HTTP-Pipelinerichtlinie bietet einen bequemen Mechanismus zum Ändern oder Ergänzen der Anforderung und der Antwort. Sie können der Pipeline, die der Benutzer oder der Entwickler der Clientbibliothek erstellt hat, benutzerdefinierte Richtlinien hinzufügen. Wenn Sie der Pipeline die Richtlinie hinzufügen, können Sie angeben, ob diese Richtlinie pro Aufruf oder pro Wiederholungsversuch ausgeführt werden soll.

Um eine benutzerdefinierte HTTP-Pipelinerichtlinie zu erstellen, erweitern Sie einfach einen Basisrichtlinientyp und implementieren eine abstrakte Methode. Anschließend können Sie die Richtlinie in die Pipeline integrieren.

Benutzerdefinierte Header in HTTP-Anforderungen

Das Azure SDK für Java-Clientbibliotheken bietet eine konsistente Möglichkeit, benutzerdefinierte Header über Context Objekte in der öffentlichen API zu definieren, wie im folgenden Beispiel gezeigt:

// Add your headers
HttpHeaders headers = new HttpHeaders();
headers.set("my-header1", "my-header1-value");
headers.set("my-header2", "my-header2-value");
headers.set("my-header3", "my-header3-value");

// Call API by passing headers in Context.
configurationClient.addConfigurationSettingWithResponse(
    new ConfigurationSetting().setKey("key").setValue("value"),
    new Context(AddHeadersFromContextPolicy.AZURE_REQUEST_HTTP_HEADERS_KEY, headers));

// The three headers are now be added to the outgoing HTTP request.

Weitere Informationen finden Sie in der AddHeadersFromContextPolicy-Klasse.

Standard-TLS/SSL-Bibliothek

Alle Clientbibliotheken verwenden standardmäßig die tomcat-native Boring SSL-Bibliothek, um die Leistung auf systemeigener Ebene für TLS/SSL-Vorgänge zu ermöglichen. Die Boring SSL-Bibliothek ist ein Uber JAR mit nativen Bibliotheken für Linux, macOS und Windows und bietet eine bessere Leistung im Vergleich zur standardmäßigen TLS/SSL-Implementierung innerhalb des JDK.

Verringern der Größe der Tomcat-nativen TLS/SSL-Abhängigkeit

Standardmäßig wird der Uber JAR der Tomcat-Native Boring SSL-Bibliothek in Azure SDKs für Java verwendet. Um die Größe dieser Abhängigkeit zu verringern, müssen Sie die Abhängigkeit mit einem os Klassifizierer als "netty-tcnativ" einschließen, wie im folgenden Beispiel gezeigt:

<project>
  ...
  <dependencies>
    ...
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-tcnative-boringssl-static</artifactId>
      <version>2.0.25.Final</version>
      <classifier>${os.detected.classifier}</classifier>
    </dependency>
    ...
  </dependencies>
  ...
  <build>
    ...
    <extensions>
      <extension>
        <groupId>kr.motd.maven</groupId>
        <artifactId>os-maven-plugin</artifactId>
        <version>1.4.0.Final</version>
      </extension>
    </extensions>
    ...
  </build>
  ...
</project>

Verwenden von JDK TLS/SSL

Wenn Sie lieber das Standardmäßige JDK TLS/SSL anstelle von Tomcat-Native Boring SSL verwenden möchten, müssen Sie die Tomcat-native Boring SSL-Bibliothek ausschließen. Beachten Sie, dass die Leistung von JDK TLS/SSL basierend auf unseren Tests 30 % langsamer ist als Tomcat-Native Boring SSL. Bei Verwendung com.azure:azure-core:1.28.0 oder höher verwaltet die HttpClientImplementierungsbibliothek (z com.azure:azure-core-http-netty. B. ) die Abhängigkeit von Tomcat-Native Boring SSL. Um die Abhängigkeit auszuschließen, fügen Sie der POM-Datei die folgende Konfiguration hinzu:

<project>
  ...
  <dependencies>
    ...
    <dependency>
     <groupId>com.azure</groupId>
       <artifactId>azure-core-http-netty</artifactId>
       <version>1.13.6</version>
       <exclusions>
         <exclusion>
           <groupId>io.netty</groupId>
           <artifactId>netty-tcnative-boringssl-static</artifactId>
         </exclusion>
       </exclusions>
    </dependency>
    ...
  </dependencies>
  ...
</project>

Nächste Schritte

Nachdem Sie nun mit der HTTP-Clientfunktionalität im Azure SDK für Java vertraut sind, erfahren Sie, wie Sie den verwendeten HTTP-Client weiter anpassen. Weitere Informationen finden Sie unter Konfigurieren von Proxys im Azure SDK für Java.