Compartilhar via


Clientes HTTP e pipelines no SDK do Azure para Java

Este artigo fornece uma visão geral do uso do cliente HTTP e da funcionalidade de pipeline no SDK do Azure para Java. Essa funcionalidade fornece uma experiência consistente, poderosa e flexível para desenvolvedores que usam todo o SDK do Azure para bibliotecas Java.

Clientes HTTP

O SDK do Azure para Java é implementado usando uma abstração HttpClient. Essa abstração permite uma arquitetura pluggável que aceita várias bibliotecas de clientes HTTP ou implementações personalizadas. No entanto, para simplificar o gerenciamento de dependência para a maioria dos usuários, todas as bibliotecas de clientes do Azure dependem de azure-core-http-netty. Assim, o cliente HTTP do Netty é o cliente padrão usado em todas as bibliotecas do SDK do Azure para Java.

Embora o Netty seja o cliente HTTP padrão, o SDK fornece três implementações de cliente, dependendo de quais dependências você já tem em seu projeto. Essas implementações são para:

Nota

O JDK HttpClient em combinação com o SDK do Azure para Java só tem suporte com o JDK 12 e superior.

Substituir o cliente HTTP padrão

Se preferir outra implementação, você poderá remover a dependência do Netty excluindo-a nos arquivos de configuração de build. Em um arquivo de pom.xml do Maven, você exclui a dependência do Netty e inclui outra dependência.

O exemplo a seguir mostra como excluir a dependência de uma sub-rede de uma dependência real da biblioteca de azure-security-keyvault-secrets. Exclua o Netty de todas as bibliotecas de com.azure apropriadas, conforme mostrado aqui:

<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>

Nota

Se você remover a dependência do Netty, mas não fornecer nenhuma implementação em seu lugar, o aplicativo não será iniciado. Uma implementação de HttpClient deve existir no classpath.

Configurar clientes HTTP

Quando você cria um cliente de serviço, o padrão é usar HttpClient.createDefault(). Esse método retorna uma instância de HttpClient básica com base na implementação do cliente HTTP fornecida. Caso você exija um cliente HTTP mais complexo, como um proxy, cada implementação oferece um construtor que permite construir uma instância de HttpClient configurada. Os construtores são NettyAsyncHttpClientBuilder, OkHttpAsyncHttpClientBuilder e JdkAsyncHttpClientBuilder.

Os exemplos a seguir mostram como criar instâncias de HttpClient usando Netty, OkHttp e o cliente HTTP do JDK 11. Essas instâncias operam como proxy através de http://localhost:3128 e autenticam com o usuário example com a senha 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();

Agora você pode passar a instância de HttpClient construída para um construtor de cliente de serviço para uso como o cliente para comunicação com o serviço. O exemplo a seguir usa a nova instância de HttpClient para criar um cliente de Blob de Armazenamento do Azure.

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

Para bibliotecas de gerenciamento, você pode definir o HttpClient durante a configuração do Gerenciador.

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

Fluxo de trabalho HTTP

O pipeline HTTP é um dos principais componentes para obter consistência e diagnóstico nas bibliotecas de clientes Java para o Azure. Um pipeline HTTP é composto de:

  • Um transporte HTTP
  • Políticas de pipeline HTTP

Você pode fornecer seu próprio pipeline HTTP personalizado ao criar um cliente. Se você não fornecer um pipeline, a biblioteca de clientes criará um configurado para trabalhar com essa biblioteca de clientes específica.

Transporte HTTP

O transporte HTTP é responsável por estabelecer a conexão com o servidor e enviar e receber mensagens HTTP. O transporte HTTP forma o gateway para que as bibliotecas de clientes do SDK do Azure interajam com os serviços do Azure. Conforme observado anteriormente neste artigo, o SDK do Azure para Java usa netty por padrão para seu transporte HTTP. No entanto, o SDK também fornece um transporte HTTP plugável para que você possa usar outras implementações quando apropriado. O SDK também fornece mais duas implementações de transporte HTTP para OkHttp e o cliente HTTP que é fornecido com o JDK 11 e posterior.

Políticas de pipeline HTTP

Um pipeline consiste em uma sequência de etapas executadas para cada viagem de ida e volta de solicitação-resposta HTTP. Cada política tem uma finalidade dedicada e atua em uma solicitação ou uma resposta ou, às vezes, ambas. Como todas as bibliotecas de cliente têm uma camada padrão do 'Azure Core', essa camada garante que cada política seja executada em ordem no pipeline. Quando você envia uma solicitação, as políticas são executadas na ordem em que são adicionadas ao pipeline. Quando você recebe uma resposta do serviço, as políticas são executadas na ordem inversa. Todas as políticas adicionadas ao pipeline são executadas antes de enviar a solicitação e depois de receber uma resposta. A política precisa decidir se deve agir na solicitação, na resposta ou em ambos. Por exemplo, uma política de registro registra a solicitação e a resposta, mas a política de autenticação está interessada em modificar apenas a solicitação.

A estrutura do Azure Core fornece a política com os dados de solicitação e resposta necessários, juntamente com qualquer contexto necessário para executar a política. A política então pode executar sua operação com os dados fornecidos e passar o controle junto com a próxima política no pipeline.

Diagrama do pipeline HTTP

Posição da política de pipeline HTTP

Quando você faz solicitações HTTP para serviços de nuvem, é importante lidar com falhas transitórias e tentar novamente tentativas com falha. Como essa funcionalidade é um requisito comum, o Azure Core fornece uma política de repetição que pode observar falhas transitórias e repetir automaticamente a solicitação.

Essa política de repetição, portanto, divide todo o pipeline em duas partes: políticas que são executadas antes da política de repetição e das políticas que são executadas após a política de repetição. As políticas adicionadas antes da política de repetição são executadas apenas uma vez por operação de API, e as políticas adicionadas após a política de repetição são executadas tantas vezes quanto as tentativas de repetição.

Portanto, ao criar o pipeline HTTP, você deve entender se deve executar uma política para cada repetição de solicitação ou uma vez por operação de API.

Políticas comuns de pipeline HTTP

Os pipelines HTTP para serviços baseados em REST têm configurações com políticas de autenticação, novas tentativas, registro em log, telemetria e especificação da ID da solicitação no cabeçalho. O Azure Core é pré-carregado com essas políticas HTTP normalmente necessárias que você pode adicionar ao pipeline.

Política Link do GitHub
política de repetição RetryPolicy.java
política de autenticação BearerTokenAuthenticationPolicy.java
política de registro em log HttpLoggingPolicy.java
política de ID de solicitação RequestIdPolicy.java
política de telemetria UserAgentPolicy.java

Política de pipeline HTTP personalizada

A política de pipeline HTTP fornece um mecanismo conveniente para modificar ou decorar a solicitação e a resposta. Você pode adicionar políticas personalizadas ao pipeline que o usuário ou o desenvolvedor da biblioteca de clientes criou. Ao adicionar a política ao pipeline, você pode especificar se essa política deve ser executada por chamada ou por repetição.

Para criar uma política de pipeline HTTP personalizada, basta estender um tipo de política base e implementar algum método abstrato. Você pode então conectar a política ao pipeline.

Cabeçalhos personalizados em solicitações HTTP

As bibliotecas de clientes do SDK do Azure para Java fornecem uma maneira consistente de definir cabeçalhos personalizados por meio de objetos Context na API pública, conforme mostrado no exemplo a seguir:

// 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.

Para mais informações, consulte a classe AddHeadersFromContextPolicy.

Biblioteca TLS/SSL padrão

Todas as bibliotecas de cliente, por padrão, usam a biblioteca SSL Boring nativa do Tomcat para habilitar o desempenho em nível nativo para operações TLS/SSL. A biblioteca BoringSSL é um JAR abrangente que contém bibliotecas nativas para Linux, macOS e Windows, e oferece melhor desempenho em comparação com a implementação padrão de TLS/SSL no JDK.

Reduzir Tomcat-Native tamanho da dependência TLS/SSL

Por padrão, o uber JAR da biblioteca BoringSSL Tomcat-Native é usado nos SDKs do Azure para Java. Para reduzir o tamanho dessa dependência, é necessário incluir a dependência com um classificador os de acordo com netty-tcnative, conforme mostrado no exemplo a seguir:

<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>

Use JDK TLS/SSL

Se você preferir usar o JDK TLS/SSL padrão em vez de Tomcat-Native Boring SSL, será necessário excluir a biblioteca SSL Boring nativa do Tomcat. Observe que, com base em nossos testes, o desempenho do JDK TLS/SSL é 30% mais lento em comparação com Tomcat-Native Boring SSL. Quando você usa com.azure:azure-core:1.28.0 ou posterior, a biblioteca que implementa o HttpClient(como com.azure:azure-core-http-netty) gerencia a dependência no Tomcat-Native Boring SSL. Para excluir a dependência, adicione a seguinte configuração ao arquivo POM:

<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>

Próximas etapas

Agora que você está familiarizado com a funcionalidade do cliente HTTP no SDK do Azure para Java, saiba como personalizar ainda mais o cliente HTTP que você está usando. Para obter mais informações, consulte Configurar proxies no SDK do Azure para Java.