Прозрачное сжатие OkHttp, сбор производительности в 10 раз, плюс ошибка

Java OKHttp

Оригинал: Miss Sister Taste (идентификатор публичной учетной записи WeChat: xjjdog), добро пожаловать, пожалуйста, сохраните источник для перепечатки.

нужно использоватьOkHttp, обязательно знайте, что это透明压缩В противном случае вы не знаете, как умереть, или вы не знаете, почему вы живете некомфортно.

В любом случае, это не очень хорошо.

Что вызвано透明压缩Шерстяная ткань? Когда OkHttp отправляет запрос, он автоматически добавит заголовок запроса gzip.Accept-Encoding:gzip. Итак, когда данные возвращаются с заголовком ответа gzipContent-Encoding=gzip, OkHttp автоматически распаковывает данные. (Accept-EncodingиContent-Encodingпредставляет собой пару заголовков запроса, соответствующих запросу и возврату соответственно)

Зачем его сжимать? Потому что это может значительно снизить пропускную способность. Для некоторых сервисов, которые не занимают много ресурсов ЦП, таких как Kafka, мы можем включить сжатие gzip, чтобы ускорить поток информации.

Насколько велика эта степень сжатия? Вы можете взглянуть на фактический скриншот ниже, для обычногоxmlилиjson, данные могут быть9MBсжато до350KBВокруг полностью достигается степень сжатия26.

Это повышает производительность системы

SpringCloudМикросервисные системы сейчас используются многими компаниями. Даже для некоторых традиционных предприятий некоторые большие объемы данныхtoBПредприятия также хотят отведать крабов.

Для простого сервиса SpringBoot нам нужно только настроить соответствующее сжатие в файле yml. Таким образом, мы открыли ссылку из браузера на веб-сервис. Этот метод сжатия спасает службы с большими объемами данных!

Конкретная конфигурация выглядит следующим образом.

server:
  port: 8082
  compression:
    enabled: true
    min-response-size: 1024
    mime-types: ["text/html","text/xml","application/xml","application/json","application/octet-stream"]

Его соответствующий класс конфигурации Spring:org.springframework.boot.web.server.Compression.

Но не будьте слишком счастливы. Из-за распределенной среды цепочка вызовов будет длиннее. Даже в интрасети передача по сети более десяти МБ займет значительное время.

Как показано на рисунке выше, запрос от браузера к реальному сервисному узлу может проходить по множеству ссылок.

  • nginx перенаправляет запросы на шлюз микросервиса zuul
  • zuul перенаправляет на конкретный микросервис A
  • Микросервис A вызывает микросервис B через интерфейс Feign.

Если большая часть наших данных предоставляется микросервисом B, медленная эффективность передачи любой из вышеперечисленных ссылок повлияет на производительность запроса.

Поэтому нам нужно включить gzip-сжатие интерфейса Feign. Использование прозрачного прокси OkHttp — самый простой способ.

Во-первых, добавьте в проект пакет jar от feign.

dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
</dependency>

Во-вторых, включите OkHttp в качестве набора инструментов клиентского запроса feign в файле yml. На всякий случай мы также заблокировали httpclient, который слишком тяжелый и слишком старый.

feign:
  httpclient:
    enabled: false
  okhttp:
    enabled: true

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

Если пакет данных вашего приложения большой и цепочка вызовов длинная, этот метод даже принесет вашему сервису数秒улучшение сексуальной активности. xjjdog однажды заставил систему улитки летать, изменив несколько параметров. Все восклицали: оказывается, сторона В может быть и С.

Как OkHttp обеспечивает прозрачное сжатие?

OkHttp обрабатывает прозрачное сжатие через перехватчики. Конкретный классokhttp3.internal.http.BridgeInterceptor.

Конкретный код выглядит следующим образом, когда считается, что нетAccept-EncodingКогда голова запустится, добавьте одну из своих.

// If we add an "Accept-Encoding: gzip" header field we're responsible for also decompressing
// the transfer stream.
boolean transparentGzip = false;
if (userRequest.header("Accept-Encoding") == null && userRequest.header("Range") == null) {
  transparentGzip = true;
  requestBuilder.header("Accept-Encoding", "gzip");
}

Наиболее важный код приведен ниже.

if (transparentGzip
    && "gzip".equalsIgnoreCase(networkResponse.header("Content-Encoding"))
    && HttpHeaders.hasBody(networkResponse)) {
  GzipSource responseBody = new GzipSource(networkResponse.body().source());
  Headers strippedHeaders = networkResponse.headers().newBuilder()
      .removeAll("Content-Encoding")
      .removeAll("Content-Length")
      .build();
  responseBuilder.headers(strippedHeaders);
  String contentType = networkResponse.header("Content-Type");
  responseBuilder.body(new RealResponseBody(contentType, -1L, Okio.buffer(responseBody)));
}

можно увидетьifВ заявлении три условия.

  • программа не установленаAccept-Encoding, с включенным прозрачным сжатием
  • сервер имеетContent-Encodingзаголовок с включенным сжатием gzip
  • Есть пакеты

Только когда эти три условия выполняются одновременно, прозрачное сжатие OkHttp будет работать и поможет нам автоматически распаковать.

Он копнул немного глубоко

К сожалению, приведенный выше код ключа, толькоif,нетelse, то есть, когда какое-либо из этих условий не выполняется, внутренние пакеты данных будут возвращены без изменений.

Нет проблем с двумя условиями 2 и 3. Нет ничего плохого в том, чтобы вернуть внутренние данные как есть Проблема заключается в первом условии.

Если вы находитесь в коде, используйте следующий код:

Request.Builder builder = chain.request()
                .newBuilder()
                .addHeader("Accept", "application/json")
                .addHeader("Accept-Encoding", "gzip");

То есть установить вручнуюAccept-Encodingинформация заголовка. Это распространено, потому что отражает строгость мышления программиста.

Именно эта строгость создает проблему.

Если ваше серверное приложение не запускается сначалаgzipСжатые, в настоящее время оба в порядке, но если ваше серверное приложение внезапно откроется в один прекрасный деньgzipСжимайте, и ваш код будет готов.

Причина в том, что сжатые gzip-пакеты на стороне сервера возвращаются как есть, и вам необходимо вручную обрабатывать сжатые gzip-пакеты.

Таким образом, не добавлять его — это хорошо, а добавлять — плохо, если только вы не хотите обрабатывать данные gzip самостоятельно.

так какOkHttpсуществуетAndroidПрименение тоже очень обширное.Если не знать этой детали, то последствия будут плачевными. Обновление клиента идет медленно, а сервер можно только честно откатить.

За интеллектом всегда стоят какие-то детали, невидимые невооруженным глазом. Так же, как за невинностью xjjdog всегда стоит застенчивость. Только когда вы узнаете его глубоко, вы познаете его красоту.

Об авторе:Мисс сестра вкус(xjjdog), публичная учетная запись, которая не позволяет программистам идти в обход. Сосредоточьтесь на инфраструктуре и Linux. Десять лет архитектуры, десятки миллиардов ежедневного трафика, обсуждение с вами мира высокой параллелизма, дающие вам другой вкус.