Восстановить TCP-соединение по HTTP 503

#java #http #okhttp #istio

#java #http #okhttp #istio

Вопрос:

Мы используем okhttp в наших Java-приложениях, развернутых на кластере k8s. В нашем исходном приложении не включен istio, и оно подключается к месту назначения с помощью envoy sidecar. Цепочка подключений выглядит следующим образом:

SRC ———> Envoy -> ЛЕТНЕЕ время

Таким образом, на самом деле приложение SRC устанавливает соединение не напрямую с приложением DST, а с прокси-сервером Envoy перед ним. Когда приложения DST завершают работу, это прерывает все соединения между DST и Envoy, но соединения между SRC и Envoy остаются открытыми. Вот почему приложение SRC начинает получать ошибки 503. Другое сообщение от SRC к DST также получает 503, потому что мы продолжаем повторно использовать незанятое соединение, установленное в пуле соединений okhttp. Решение этой проблемы заключается в восстановлении нового TCP-соединения вместо использования одного из незанятых соединений из пула соединений. Можно ли настроить okhttp для завершения всего TCP-соединения на основе одного полученного HTTP 503?

Ответ №1:

Что-то вроде этого должно работать

 import okhttp3.OkHttpClient
import okhttp3.Request

fun main() {
  val client = OkHttpClient.Builder()
    .eventListenerFactory(LoggingEventListener.Factory())
    .addNetworkInterceptor { chain ->
      chain.proceed(chain.request()).also { response ->
        println(response.code)
        if (response.code == 503) {
          println("closing")
          chain.connection()?.socket()?.close()
        }
      }
    }
    .build()

  val response1 = client.newCall(Request.Builder().url("https://httpbin.org/get").build()).execute()

  val response2 = client.newCall(Request.Builder().url("https://httpbin.org/status/503").build()).execute()

  val response3 = client.newCall(Request.Builder().url("https://httpbin.org/get").build()).execute()
}
  

Комментарии:

1. Мне нравится, что на вопрос Java был дан ответ в Kotlin!!! Я так люблю Kotlin.

Ответ №2:

Вот что я использую в Java 17

 private final OkHttpClient client = new OkHttpClient.Builder().addNetworkInterceptor(c -> {
    var response = c.proceed(c.request());
    if (response.code() == 503) {
        c.connection().socket().close();
    }
    return response;
}).build();