Я пытаюсь непрерывно отправлять запросы GET и POST API REST каждые несколько минут. Проблема в том, что после ровно 1000 запросов я получаю кадр GOAWAY
(и IOException
):
Кадр GOAWAY (тип = 0x7) используется для инициирования отключения соединения или сигнализации о серьезных ошибках.
HTTP / 2 spec
Я провел немало исследований и обнаружил, что не только 1000 запросов максимальное значение по умолчанию nginx , Cloudfront ( связанная с Chromium проблема ) и Discord также демонстрируют аналогичное поведение.
Я попытался воспроизвести эту проблему на локальном сервере nginx с конфигурацией HTTP / 2 по умолчанию:
server {
listen 443 http2 ssl;
http2_max_requests 1000;
...
}
var client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.build();
for (var i = 0; i < 1100; i++) {
var url = URI.create(String.format("https://localhost/images/test%d.jpg", i));
var request = HttpRequest.newBuilder().uri(url).build();
client.send(request, HttpResponse.BodyHandlers.discarding());
System.out.printf("Image %d processed%n", i);
}
И после примерно 1000 запросов я получаю GOAWAY
ошибку, как и ожидалось:
...
Image 998 processed
<b>Exception in thread "main" java.io.IOException: /127.0.0.1:49259: GOAWAY received</b>
Моей первой мыслью было бы проверить, содержит ли сообщение об исключении строку "GOAWAY"
, и затем повторить запрос соответственно:
try {
client.send(request, HttpResponse.BodyHandlers.discarding());
} catch (IOException e) {
if (e.getMessage().contains("GOAWAY")) {
client.send(request, HttpResponse.BodyHandlers.discarding());
} else throw e;
}
Моя проблема с этим подходом заключается в том, что сравнение строк может показаться хрупким. Кроме того, так как все, что у меня есть, это IOException с сообщением, я не могу отличить GOAWAY
фреймов с подлинным кодом ошибки (в этом случае я, вероятно, должен прекратить отправку запросов) и тех, у которых NO_ERROR
(в этом случае я возможно, можно повторить запрос).
Как правильно обрабатывать / обрабатывать GOAWAY
ошибок (не считая использования HTTP / 1.1)?