日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java keeplive,java http长链接(keep-alive)导致的问题

發(fā)布時間:2025/3/21 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java keeplive,java http长链接(keep-alive)导致的问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

兩種由http長鏈接(keep-alive)導(dǎo)致的問題,當然這兩種問題都有多種原因?qū)е?#xff0c;這里只分析針對keep-alive相關(guān)而產(chǎn)生的異常。

1 SocketException: Connection reset

報錯堆棧日志:

Caused by: java.net.SocketException: Connection reset

at java.net.SocketInputStream.read(SocketInputStream.java:209)

at java.net.SocketInputStream.read(SocketInputStream.java:141)

at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)

at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)

at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282)

at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)

at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)

at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)

at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)

at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165)

at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)

at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)

at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)

at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)

at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)

at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)

at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)

at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)

at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:221)

at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165)

at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:140)

復(fù)制代碼

本質(zhì)原因是 服務(wù)器通過TCP協(xié)議給客戶端返回了RST消息,表示已經(jīng)完成了發(fā)送和接收,如果客戶端此時從流中讀取數(shù)據(jù)時會發(fā)生Connection reset,往流中寫數(shù)據(jù)時就會發(fā)生Connection reset Connection reset by peer。注意Socket.close()語義和TCP FIN消息之間略有不匹配。

而至于為什么服務(wù)端會返回 RST消息,那就是http keep-alive 導(dǎo)致的問題了。

如果是springboot的服務(wù)器,那么默認的keep-alive timeout是60s,如果客戶端使用的是apache httpclient,默認的keep-alive是在

org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy類設(shè)置的,代碼如下:

public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {

Args.notNull(response, "HTTP response");

final HeaderElementIterator it = new BasicHeaderElementIterator(

response.headerIterator(HTTP.CONN_KEEP_ALIVE));

while (it.hasNext()) {

final HeaderElement he = it.nextElement();

final String param = he.getName();

final String value = he.getValue();

if (value != null && param.equalsIgnoreCase("timeout")) {

try {

return Long.parseLong(value) * 1000;

} catch(final NumberFormatException ignore) {

}

}

}

return -1;

}

復(fù)制代碼

可見,如果response header如果沒有返回Keep-Alive,那么就會是-1,也就是無限的, hc.apache.org/httpcompone… "If the Keep-Alive header is not present in the response, HttpClient assumes the connection can be kept alive indefinitely"

所以問題就比較明白了,springboot服務(wù)端沒有返回Keep-Alive的header,客戶端如果使用了apache httpclient,且沒有設(shè)置Keep-Alive的話,就會導(dǎo)致服務(wù)端的超時是60s,客戶端就認為是無限的,在某些情況下,服務(wù)端關(guān)閉了鏈接,客戶端還會獲取這個連接,就會導(dǎo)致上面的問題。

既然找到原因了那么就需要解決,httpclient文檔中也給了說要設(shè)置默認的超時時間,即給一個自定義的實現(xiàn)。

2 NoHttpResponseException: xxx.xxx.xxx.xxx failed to respond

Caused by: org.apache.http.NoHttpResponseException: xxx.xxx.xxx.xxx failed to respond

at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141)

at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)

at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)

at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)

at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165)

at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)

at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)

at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)

at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)

at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)

at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)

at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)

at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)

at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:221)

at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165)

at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:140)

復(fù)制代碼

補充知識點:

1 'Connection: Keep-Alive' header頭只用來在HTTP 1.0中, 而在HTTP 1.1中默認都是Keep-Alive的,所以不需要再添加'Connection: Keep-Alive'的頭。所以在springboot1.5以上版本中,即使你在請求的header中加了'Connection: Keep-Alive'的頭,在返回的header中是沒有Connection的。相關(guān)鏈接: github.com/spring-proj…

2 curl 命令可以使用--http1.0 來強制走http1.0協(xié)議。

3 springboot中 tomcat 默認的keepalive timeout是60s, github.com/spring-proj…

總結(jié)

以上是生活随笔為你收集整理的java keeplive,java http长链接(keep-alive)导致的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。