我正在嘗試每隔幾分鐘連續向 REST API 發送 GET 和 POST 請求。問題是,恰好在 1000 個請求之后,我收到一個GOAWAY框架(和一個IOException):GOAWAY 幀(類型=0x7)用于啟動連接關閉或發出嚴重錯誤情況的信號?!?6.8,RFC 7540我做了一些研究,發現不僅 1000 個請求是nginx 的默認最大值,Cloudfront(相關 Chromium 問題)和 Discord 也表現出相同的行為。我嘗試使用默認 HTTP/2 配置的本地 nginx 服務器重現此問題:服務器 { 聽 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預期的錯誤:...圖片 998 已處理線程“主”java.io.IOException 中的異常:/127.0.0.1:49259:收到 GOAWAY我的第一個想法是檢查異常消息是否包含字符串"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)?
1 回答

慕少森
TA貢獻2019條經驗 獲得超9個贊
服務器有權隨時以任何理由關閉連接。
在 HTTP/2GOAWAY
幀中指示服務器處理的最后一個流是什么,因此客戶端可以知道當連接關閉時需要重新發送什么流。
不幸的lastStreamId
是,沒有出現在 中java.net.http.HttpClient
,因此無法知道它并采取適當的措施。
lastStreamId
您的替代方法可能是GOAWAY
使用其他支持顯示lastStreamId
.
[免責聲明,我是 Jetty HTTP/2 實施者]
Jetty 支持較低級別的 HTTP/2 客戶端,您可以將其用于您的用例 - 您可能想嘗試一下。HTTP2Client
您可以在此處找到如何使用 Jetty 的示例。
添加回答
舉報
0/150
提交
取消