我正在嘗試每隔幾分鐘連續(xù)向 REST API 發(fā)送 GET 和 POST 請(qǐng)求。問(wèn)題是,恰好在 1000 個(gè)請(qǐng)求之后,我收到一個(gè)GOAWAY框架(和一個(gè)IOException):GOAWAY 幀(類(lèi)型=0x7)用于啟動(dòng)連接關(guān)閉或發(fā)出嚴(yán)重錯(cuò)誤情況的信號(hào)?!?6.8,RFC 7540我做了一些研究,發(fā)現(xiàn)不僅 1000 個(gè)請(qǐng)求是nginx 的默認(rèn)最大值,Cloudfront(相關(guān) Chromium 問(wèn)題)和 Discord 也表現(xiàn)出相同的行為。我嘗試使用默認(rèn) HTTP/2 配置的本地 nginx 服務(wù)器重現(xiàn)此問(wèn)題:服務(wù)器 { 聽(tīng) 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 個(gè)請(qǐng)求之后,我收到了GOAWAY預(yù)期的錯(cuò)誤:...圖片 998 已處理線程“主”java.io.IOException 中的異常:/127.0.0.1:49259:收到 GOAWAY我的第一個(gè)想法是檢查異常消息是否包含字符串"GOAWAY",然后相應(yīng)地重試請(qǐng)求:try { client.send(request, HttpResponse.BodyHandlers.discarding());} catch (IOException e) { if (e.getMessage().contains("GOAWAY")) { client.send(request, HttpResponse.BodyHandlers.discarding()); } else throw e;}我對(duì)這種方法的問(wèn)題是字符串比較似乎很脆弱。此外,由于我所擁有的只是帶有消息的 IOException,因此我無(wú)法區(qū)分GOAWAY具有真正錯(cuò)誤代碼的幀(在這種情況下我可能應(yīng)該停止發(fā)送請(qǐng)求)和那些具有NO_ERROR(在這種情況下我可能會(huì)重試請(qǐng)求) .我應(yīng)該如何正確處理/處理GOAWAY錯(cuò)誤(除了改用 HTTP/1.1)?
1 回答

慕少森
TA貢獻(xiàn)2019條經(jīng)驗(yàn) 獲得超9個(gè)贊
服務(wù)器有權(quán)隨時(shí)以任何理由關(guān)閉連接。
在 HTTP/2GOAWAY
幀中指示服務(wù)器處理的最后一個(gè)流是什么,因此客戶端可以知道當(dāng)連接關(guān)閉時(shí)需要重新發(fā)送什么流。
不幸的lastStreamId
是,沒(méi)有出現(xiàn)在 中java.net.http.HttpClient
,因此無(wú)法知道它并采取適當(dāng)?shù)拇胧?/p>
lastStreamId
您的替代方法可能是GOAWAY
使用其他支持顯示lastStreamId
.
[免責(zé)聲明,我是 Jetty HTTP/2 實(shí)施者]
Jetty 支持較低級(jí)別的 HTTP/2 客戶端,您可以將其用于您的用例 - 您可能想嘗試一下。HTTP2Client
您可以在此處找到如何使用 Jetty 的示例。
添加回答
舉報(bào)
0/150
提交
取消