Клиенты и конвейеры HTTP в пакете Azure SDK для Java

В этой статье приводятся общие сведения об использовании функциональных возможностей клиентов и конвейеров HTTP в пакете Azure SDK для Java. Они обеспечивают согласованное, эффективное и гибкое взаимодействие с системой для разработчиков, которые пользуются всеми библиотеками Azure SDK для Java.

HTTP-клиенты

Пакет Azure SDK для Java реализуется на основе абстракции HttpClient. Эта абстракция позволяет создать модульную архитектуру с подключением множества клиентских библиотек HTTP или пользовательских реализаций. Но все клиентские библиотеки Azure имеют зависимость от azure-core-http-netty, что для большинства пользователей позволяет упростить управление зависимостями. Соответственно, HTTP-клиент Netty используется по умолчанию во всех библиотеках Azure SDK для Java.

Несмотря на использование Netty в качестве HTTP-клиента по умолчанию, пакет SDK предоставляет три реализации клиента, выбор между которыми определяется другими зависимостями проекта. К ним относятся:

Примечание.

JDK HttpClient в сочетании с пакетом SDK Azure для Java поддерживается только с JDK 12 и выше.

Замена HTTP-клиента по умолчанию

Если вы предпочитаете другую реализацию, вы можете удалить зависимость от Netty из файлов конфигурации сборки. В файле Maven pom.xml нужно убрать зависимость от Netty и добавить другую зависимость.

В следующем примере показано, как исключить зависимость от Netty из реальной зависимости от библиотеки azure-security-keyvault-secrets. Не забудьте исключить Netty из всех соответствующих библиотек com.azure, как показано ниже:

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

Примечание.

Если вы удаляете зависимость Netty, но не предоставляете его реализацию, приложение не запускается. В пути классов должна существовать реализация HttpClient.

Настройка HTTP-клиентов

При создании клиента службы он по умолчанию используется HttpClient.createDefault(). Этот метод возвращает базовый экземпляр HttpClient на основе предоставленной реализации HTTP-клиента. Если вам нужен более сложный HTTP-клиент, например прокси-сервер, вы можете создать специально настроенный экземпляр HttpClient с помощью построителя, который предоставляется в каждой реализации. Это построители NettyAsyncHttpClientBuilder, OkHttpAsyncHttpClientBuilder и JdkAsyncHttpClientBuilder.

В следующих примерах показано, как скомпилировать экземпляры HttpClient с применением Netty, OkHttp и HTTP-клиента из JDK 11. Эти экземпляры используют http://localhost:3128 в качестве прокси-сервера и выполняют аутентификацию с именем пользователя example и паролем 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();

После этого созданный экземпляр HttpClient можно передать в построитель клиента службы, чтобы использовать в качестве клиента для взаимодействия с этой службой. В следующем примере новый экземпляр HttpClient применяется для компиляции клиента Azure Storage Blob.

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

Для библиотек управления значение HttpClient можно задать во время настройки диспетчера.

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

Конвейер HTTP

Конвейер HTTP является одним из ключевых компонентов для достижения согласованности и поддержки диагностики в клиентских библиотеках Java для Azure. Конвейер HTTP состоит из следующих элементов:

  • транспорт HTTP;
  • политики конвейера HTTP.

При создании клиента вы можете указать собственный настраиваемый конвейер HTTP. Если вы не предоставляете конвейер, клиентская библиотека создает клиентскую библиотеку, настроенную для работы с этой конкретной клиентской библиотекой.

Транспорт HTTP

Транспорт HTTP отвечает за установление подключения к серверу, за отправку и получение HTTP-сообщений. Транспорт HTTP формирует шлюз для клиентских библиотек пакета Azure SDK, через который они взаимодействуют со службами Azure. Как отмечалось ранее в этой статье, пакет Azure SDK для Java использует Netty в качестве транспорта HTTP по умолчанию. Но этот же пакет SDK предоставляет и отдельный подключаемый транспорт HTTP, что позволяет по мере необходимости использовать другие реализации. Также пакет SDK предоставляет две дополнительные реализации транспорта HTTP для OkHttp и HTTP-клиента, который входит в состав JDK 11 и более поздних версий.

политики конвейера HTTP.

Конвейер HTTP состоит из последовательности шагов, которые выполняются для каждой пары "запрос — ответ". Каждая политика имеет специальное назначение и действует по запросу или ответу или иногда обоим. Все клиентские библиотеки включают стандартный уровень "Azure Core", что гарантирует правильный порядок выполнения политик в конвейере. При обработке запроса политики выполняются в том порядке, в котором были добавлены в конвейер. При обработке ответа от службы те же политики выполняются в обратном порядке. Все добавленные в конвейер политики выполняются перед отправкой запроса и после получения ответа. Политика должна сама решить, будет ли она выполнять какие-то действия для запроса, для ответа или для обоих. Например, политика ведения журнала регистрирует запрос и ответ, но политика проверки подлинности заинтересована только в изменении запроса.

Платформа Azure Core предоставляет политику с необходимыми данными запроса и ответа вместе с любым необходимым контекстом для выполнения политики. На их основе политика может выполнить требуемые действия с данными и передать управление следующей политике в конвейере.

HTTP pipeline diagram

Расположение политики в конвейере HTTP

При выполнении HTTP-запросов к облачным службам важно правильно обрабатывать временные сбои и выполнять повторные попытки. Поскольку эти возможности требуются во многих случаях, Azure Core предоставляет стандартную политику повторных попыток, которая умеет отслеживать временные сбои и автоматически повторять запрос.

Таким образом политика повторных попыток разделяет весь конвейер на две части: политики, которые выполняются до политики повтора, и политики, которые выполняются после нее. Политики, добавляемые перед политикой повтора, выполняются только один раз для каждой операции API, а политики, добавленные после политики повтора, выполняются столько же раз, сколько будет выполнено попыток.

Это означает, что при создании конвейера HTTP важно хорошо понимать, какие политики нужно применять для каждого повтора запроса, а какие — один раз для операции API.

Типичные политики в конвейере HTTP

Конвейеры HTTP для служб на основе интерфейсов REST имеют в своей конфигурации политики для аутентификации, повторных попыток, ведения журнала, телеметрии и указания идентификатора запроса в заголовке. Azure Core предварительно загружается с этими часто необходимыми политиками HTTP, которые можно добавить в конвейер.

Полис Ссылка на GitHub
Политика повторных попыток RetryPolicy.java
Политика проверки подлинности BearerTokenAuthenticationPolicy.java
Политика ведения журнала HttpLoggingPolicy.java
Политика идентификатора запроса RequestIdPolicy.java
Политика телеметрии UserAgentPolicy.java

Настраиваемая политика в конвейере HTTP

Политика конвейера HTTP представляет собой удобный механизм для изменения или дополнения запросов и ответов. Пользовательские политики можно добавить в конвейер, созданный пользователем или разработчиком клиентской библиотеки. При добавлении политики в конвейер вы можете указать, нужно ли выполнять эту политику для каждого вызова или для каждой попытки.

Чтобы создать настраиваемую политику конвейера HTTP, достаточно расширить базовый тип политики и реализовать некоторый абстрактный метод. Готовую политику можно подключить к конвейеру.

Пользовательские заголовки в HTTP-запросах

Клиентские библиотеки Пакета SDK Azure для Java обеспечивают согласованный способ определения настраиваемых заголовков через Context объекты в общедоступном API, как показано в следующем примере:

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

Дополнительные сведения см. в классе AddHeadersFromContextPolicy.

Библиотека TLS/SSL по умолчанию

Все клиентские библиотеки по умолчанию используют библиотеку SSL tomcat-native Boring, чтобы обеспечить производительность на уровне машинного уровня для операций TLS/SSL. Скучная библиотека SSL — это JAR-файл uber, содержащий собственные библиотеки для Linux, macOS и Windows, и обеспечивает более высокую производительность по сравнению с реализацией TLS/SSL по умолчанию в JDK.

Уменьшение размера зависимостей TLS/SSL tomcat-Native

По умолчанию JAR-файл Uber библиотеки SSL Tomcat-Native Boring используется в пакетах SDK Azure для Java. Чтобы уменьшить размер этой зависимости, необходимо включить зависимость с классификатором os в виде netty-tcnative, как показано в следующем примере:

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

Использование ПРОТОКОЛА TLS/SSL JDK

Если вы предпочитаете использовать протокол SSL по умолчанию JDK TLS/SSL вместо Tomcat-Native Boring SSL, необходимо исключить библиотеку SSL tomcat-native Boring SSL. Помните, что на основе наших тестов производительность ПРОТОКОЛА JDK TLS/SSL составляет 30 % медленнее по сравнению с SSL tomcat-Native Boring SSL. При использовании или более поздней версии com.azure:azure-core:1.28.0 реализация библиотеки (напримерcom.azure:azure-core-http-netty) HttpClientуправляет зависимостью от SSL Tomcat-Native Boring. Чтобы исключить зависимость, добавьте следующую конфигурацию в файл 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>

Следующие шаги

Теперь, когда вы знакомы с функциями клиента HTTP в пакете SDK Azure для Java, узнайте, как дополнительно настроить http-клиент, который вы используете. Дополнительные сведения см. в разделе "Настройка прокси-серверов" в пакете SDK Azure для Java.