Ajax request occasionally stalled for a long time in chrome.
Ajax请求有时会在chrome中停留很长时间。
I finally managed to reproduced it and save all related data necessary to post here if anyone could help me out.
我终于成功地复制了它,并保存了所有相关的数据,以张贴在这里,如果有人可以帮助我。
The timeline from Chrome Dev Tool shows the request stalled for 42.62s as the following screen capture shows:
Chrome开发工具的时间线显示了42.62s的请求被延迟,如下图所示:
and within the chrome://net-internals/#events
(for the events log please head to the end) page I found the most time is cost by two events:
在chrome://net-internals/#events(事件日志请转到最后)页面中,我发现最多的时间是花费在两个事件上:
- +HTTP_TRANSACTION_READ_HEADERS [dt=21301]
- + HTTP_TRANSACTION_READ_HEADERS(dt = 21301)
- +HTTP_TRANSACTION_READ_HEADERS [dt=21304]
- + HTTP_TRANSACTION_READ_HEADERS(dt = 21304)
both get ERR_CONNECTION_RESET
.
都得到ERR_CONNECTION_RESET。
I think the error is the reason why the request stalled for so long.
我认为错误是请求拖延这么久的原因。
Any one could explain the errors?
谁能解释这些错误?
FOLLOWING IS THE EVENTS LOG FOR THE REQUEST, I also export the full events as json you can get from here then restore within the Chrome chrome://net-internals/#events
page. note the request url is internal so maybe cant access from public network:
接下来是请求的事件日志,我还将所有事件导出为json,然后在Chrome://net-internals/# EVENTS页面中恢复。注意,请求url是内部的,所以可能无法从公共网络访问:
193486: URL_REQUEST
http://qa.tieba.baidu.com/release/getReleaseHistory?projectId=fum1.0.593
Start Time: 2015-01-02 17:51:05.323
t= 1 [st= 0] +REQUEST_ALIVE [dt=42741]
t= 1 [st= 0] URL_REQUEST_DELEGATE [dt=0]
t= 1 [st= 0] +URL_REQUEST_START_JOB [dt=42740]
--> load_flags = 339804160 (BYPASS_DATA_REDUCTION_PROXY | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VERIFY_EV_CERT)
--> method = "GET"
--> priority = "LOW"
--> url = "http://qa.tieba.baidu.com/release/getReleaseHistory?projectId=fum1.0.593"
t= 2 [st= 1] URL_REQUEST_DELEGATE [dt=0]
t= 2 [st= 1] HTTP_CACHE_GET_BACKEND [dt=0]
t= 2 [st= 1] HTTP_CACHE_OPEN_ENTRY [dt=0]
t= 2 [st= 1] HTTP_CACHE_ADD_TO_ENTRY [dt=0]
t= 2 [st= 1] HTTP_CACHE_READ_INFO [dt=0]
t= 2 [st= 1] URL_REQUEST_DELEGATE [dt=0]
t= 2 [st= 1] +HTTP_STREAM_REQUEST [dt=2]
t= 4 [st= 3] HTTP_STREAM_REQUEST_BOUND_TO_JOB
--> source_dependency = 193488 (HTTP_STREAM_JOB)
t= 4 [st= 3] -HTTP_STREAM_REQUEST
t= 4 [st= 3] +HTTP_TRANSACTION_SEND_REQUEST [dt=0]
t= 4 [st= 3] HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /release/getReleaseHistory?projectId=fum1.0.593 HTTP/1.1
Host: qa.tieba.baidu.com
Connection: keep-alive
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Referer: http://qa.tieba.baidu.com/project/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: [268 bytes were stripped]
t= 4 [st= 3] -HTTP_TRANSACTION_SEND_REQUEST
t= 4 [st= 3] +HTTP_TRANSACTION_READ_HEADERS [dt=21301]
t= 4 [st= 3] HTTP_STREAM_PARSER_READ_HEADERS [dt=21301]
--> net_error = -101 (ERR_CONNECTION_RESET)
t=21305 [st=21304] HTTP_TRANSACTION_RESTART_AFTER_ERROR
--> net_error = -101 (ERR_CONNECTION_RESET)
t=21305 [st=21304] -HTTP_TRANSACTION_READ_HEADERS
t=21305 [st=21304] +HTTP_STREAM_REQUEST [dt=3]
t=21307 [st=21306] HTTP_STREAM_REQUEST_BOUND_TO_JOB
--> source_dependency = 193494 (HTTP_STREAM_JOB)
t=21308 [st=21307] -HTTP_STREAM_REQUEST
t=21308 [st=21307] +HTTP_TRANSACTION_SEND_REQUEST [dt=3]
t=21308 [st=21307] HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /release/getReleaseHistory?projectId=fum1.0.593 HTTP/1.1
Host: qa.tieba.baidu.com
Connection: keep-alive
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Referer: http://qa.tieba.baidu.com/project/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: [268 bytes were stripped]
t=21311 [st=21310] -HTTP_TRANSACTION_SEND_REQUEST
t=21311 [st=21310] +HTTP_TRANSACTION_READ_HEADERS [dt=21304]
t=21311 [st=21310] HTTP_STREAM_PARSER_READ_HEADERS [dt=21304]
--> net_error = -101 (ERR_CONNECTION_RESET)
t=42615 [st=42614] HTTP_TRANSACTION_RESTART_AFTER_ERROR
--> net_error = -101 (ERR_CONNECTION_RESET)
t=42615 [st=42614] -HTTP_TRANSACTION_READ_HEADERS
t=42615 [st=42614] +HTTP_STREAM_REQUEST [dt=12]
t=42627 [st=42626] HTTP_STREAM_REQUEST_BOUND_TO_JOB
--> source_dependency = 193498 (HTTP_STREAM_JOB)
t=42627 [st=42626] -HTTP_STREAM_REQUEST
t=42627 [st=42626] +HTTP_TRANSACTION_SEND_REQUEST [dt=2]
t=42627 [st=42626] HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /release/getReleaseHistory?projectId=fum1.0.593 HTTP/1.1
Host: qa.tieba.baidu.com
Connection: keep-alive
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Referer: http://qa.tieba.baidu.com/project/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: [268 bytes were stripped]
t=42629 [st=42628] -HTTP_TRANSACTION_SEND_REQUEST
t=42629 [st=42628] +HTTP_TRANSACTION_READ_HEADERS [dt=112]
t=42629 [st=42628] HTTP_STREAM_PARSER_READ_HEADERS [dt=112]
t=42741 [st=42740] HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 200 OK
Date: Fri, 02 Jan 2015 09:51:48 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache
tracecode: 31079600320335034634010217
tracecode: 31079600320537995786010217
Server: Apache
t=42741 [st=42740] -HTTP_TRANSACTION_READ_HEADERS
t=42741 [st=42740] HTTP_CACHE_WRITE_INFO [dt=0]
t=42741 [st=42740] HTTP_CACHE_WRITE_DATA [dt=0]
t=42741 [st=42740] HTTP_CACHE_WRITE_INFO [dt=0]
t=42741 [st=42740] URL_REQUEST_DELEGATE [dt=0]
t=42741 [st=42740] -URL_REQUEST_START_JOB
t=42741 [st=42740] URL_REQUEST_DELEGATE [dt=0]
t=42741 [st=42740] HTTP_TRANSACTION_READ_BODY [dt=0]
t=42741 [st=42740] HTTP_CACHE_WRITE_DATA [dt=0]
t=42741 [st=42740] HTTP_TRANSACTION_READ_BODY [dt=0]
t=42741 [st=42740] HTTP_CACHE_WRITE_DATA [dt=0]
t=42742 [st=42741] -REQUEST_ALIVE
EDIT:related issue Issue 447463: Chrome-network: Long delay before RST message on stale sockets results in slow page loads.
编辑:相关问题447463:Chrome-network:在陈旧套接字上的RST消息导致页面加载缓慢之前的长时间延迟。
2 个解决方案
#1
12
I once encountered a similar problem. The cause of the problem is that every browser has a limit to the maximum number of TCP connections to a server. For chrome, the limit is six. The problem is more prominent when you are using a proxy server, because all the requests go the same server (the proxy server).
我曾经遇到过类似的问题。问题的原因是每个浏览器都有一个到服务器的TCP连接的最大数量的限制。对于chrome,限制是6。当您使用代理服务器时,这个问题更加突出,因为所有的请求都指向同一个服务器(代理服务器)。
Chrome doesn't allow you to change this limit. It shouldn't in fact. If you want to know more about why this limit exists, and what are the limits for other browsers, you can read this article.
Chrome不允许你改变这个限制。事实上它不应该。如果您想了解为什么存在这种限制,以及其他浏览器的限制是什么,您可以阅读本文。
The reason why this limit is rarely a problem is because multiple HTTP requests to the same host are mostly sent consecutively, rather than parallely, preferably over the same TCP connection.
这个限制很少出现问题的原因是,对同一个主机的多个HTTP请求大部分是连续发送的,而不是并行发送的,最好是通过相同的TCP连接。
If this problem occurs to you frequently, then the reason might be:
如果这个问题经常发生在你身上,那么原因可能是:
-
Server doesn't support persistent TCP connection: If the problem occurs only when accessing a particular server, the reason might be that chrome is fetching multiple resources (like images, CSS files, etc) on parallel connections. Since, in your case, the server is on your local network, you might want to ask the server's administrator to add support for persistent TCP connections.
服务器不支持持久的TCP连接:如果问题只发生在访问特定的服务器时,原因可能是chrome在并行连接上获取多个资源(如图像、CSS文件等)。由于在您的示例中,服务器位于您的本地网络上,您可能需要请求服务器的管理员添加对持久TCP连接的支持。
-
Multiple persistent connections are open: If you are working behind a proxy server, then downloading multiple files simultaneously or opening sites which keep a TCP connection open might be the cause of your problem.To get rid of it, all you can do is to not download many things simultaneously (or download in a different browser, if you have to).
多个持久连接是打开的:如果您正在代理服务器的后面工作,那么同时下载多个文件或者打开一个打开TCP连接的站点可能会导致您的问题。为了摆脱它,你所能做的就是不同时下载很多东西(或者在不同的浏览器中下载,如果有必要的话)。
PS: The error net_error = -101 (ERR_CONNECTION_RESET) is not due to invalid headers, it is because of the timeout, waiting for some previous connection to the server to close.
PS:错误net_error = -101 (ERR_CONNECTION_RESET)不是由于头文件无效,而是由于超时,等待与服务器的一些先前连接关闭。
#2
9
Similar issue here and it appears that after a while, approx 3 minutes a socket chrome is trying to use is closed (I assume) by the OS.
类似的问题也出现了,过了一段时间,chrome尝试使用的插座大约3分钟就会被操作系统关闭(我猜)。
This is listed as a bug in the chromium forum as well. I'm guessing lack of some sort of "keep-alive" mechanism.: https://code.google.com/p/chromium/issues/detail?id=447463
这也是chromium论坛中的一个bug。我猜是缺少某种“维持生命”的机制。:https://code.google.com/p/chromium/issues/detail?id=447463
My error message is slightly different but it could be due to my application making the calls over SSL. Here's what I see in chrome://net-internals:
我的错误消息略有不同,但这可能是因为我的应用程序通过SSL进行调用。以下是我在chrome://net内部网中看到的:
First chrome finds an existing socket and the request is associated with it (HTTP_STREAM_JOB):
首先,chrome找到一个现有的套接字,请求与它关联(HTTP_STREAM_JOB):
t=1572 [st=0] HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION
--> source_dependency = 1347215 (HTTP2_SESSION)
t=1572 [st=0] HTTP_STREAM_JOB_BOUND_TO_REQUEST
--> source_dependency = 1348612 (URL_REQUEST)
t=1572 [st=0] -HTTP_STREAM_JOB
Then back in (URL_REQUEST) you will see it time out, note the 10 seconds lapse in time from t=1572 to t=11573:
然后返回(URL_REQUEST),你会看到它超时了,注意从t=1572到t=11573的10秒间隔:
t= 1572 [st= 0] HTTP2_SESSION_SEND_DATA
--> fin = true
--> size = 48
--> stream_id = 3
t= 1572 [st= 0] HTTP2_SESSION_UPDATE_SEND_WINDOW
--> delta = -48
--> window_size = 2147483551
t=11573 [st=10001] HTTP2_SESSION_CLOSE
--> description = "Failed ping."
--> net_error = -352 (ERR_SPDY_PING_FAILED)
Clearly there is a timeout when chrome attempts to adjust the window size on the existing socket. I assume this is due to inactivity on the socket.
显然,当chrome试图调整现有套接字上的窗口大小时,会出现超时。我认为这是由于套接字不活动造成的。
I'm going to try to implement some sort of heartbeat request at perhaps 60 sec interval to see if the issue still persists. I'll post an update with results.
我将尝试在大约60秒的间隔内实现某种心跳请求,看看这个问题是否仍然存在。我将更新结果。
UPDATE:
更新:
Added the following code to javascript that's loaded on every page. This is retrieving an empty html doc from the public root:
将以下代码添加到每个页面上加载的javascript中。这是从公共根目录检索空的html文档:
$(document).ready(function() {
$.keepalive =
setInterval(function() {
$.ajax({
url: '/ping.html',
cache: false
});
}, 60000);
});
This appears to have helped keep the socket open even with the sample below showing approx 6 minutes between "real" calls:
这似乎有助于保持插座打开,即使下面的示例显示在“真正的”调用之间大约6分钟:
At 570B per call in 60 sec intervals the ping call would add around 800kb of bandwidth usage per 24 hrs (per browser session). I'm not sure how much CPU overhead on the server this would cause.
每调用一次570B,每隔60秒,ping调用每24小时(每个浏览器会话)将增加大约800kb的带宽使用。我不确定这会在服务器上造成多少CPU开销。
For comparison, the BEFORE:
相比之下,前:
There has to be a better solution but i haven't been able to locate one yet.
必须有更好的解决方案,但我还没找到。
#1
12
I once encountered a similar problem. The cause of the problem is that every browser has a limit to the maximum number of TCP connections to a server. For chrome, the limit is six. The problem is more prominent when you are using a proxy server, because all the requests go the same server (the proxy server).
我曾经遇到过类似的问题。问题的原因是每个浏览器都有一个到服务器的TCP连接的最大数量的限制。对于chrome,限制是6。当您使用代理服务器时,这个问题更加突出,因为所有的请求都指向同一个服务器(代理服务器)。
Chrome doesn't allow you to change this limit. It shouldn't in fact. If you want to know more about why this limit exists, and what are the limits for other browsers, you can read this article.
Chrome不允许你改变这个限制。事实上它不应该。如果您想了解为什么存在这种限制,以及其他浏览器的限制是什么,您可以阅读本文。
The reason why this limit is rarely a problem is because multiple HTTP requests to the same host are mostly sent consecutively, rather than parallely, preferably over the same TCP connection.
这个限制很少出现问题的原因是,对同一个主机的多个HTTP请求大部分是连续发送的,而不是并行发送的,最好是通过相同的TCP连接。
If this problem occurs to you frequently, then the reason might be:
如果这个问题经常发生在你身上,那么原因可能是:
-
Server doesn't support persistent TCP connection: If the problem occurs only when accessing a particular server, the reason might be that chrome is fetching multiple resources (like images, CSS files, etc) on parallel connections. Since, in your case, the server is on your local network, you might want to ask the server's administrator to add support for persistent TCP connections.
服务器不支持持久的TCP连接:如果问题只发生在访问特定的服务器时,原因可能是chrome在并行连接上获取多个资源(如图像、CSS文件等)。由于在您的示例中,服务器位于您的本地网络上,您可能需要请求服务器的管理员添加对持久TCP连接的支持。
-
Multiple persistent connections are open: If you are working behind a proxy server, then downloading multiple files simultaneously or opening sites which keep a TCP connection open might be the cause of your problem.To get rid of it, all you can do is to not download many things simultaneously (or download in a different browser, if you have to).
多个持久连接是打开的:如果您正在代理服务器的后面工作,那么同时下载多个文件或者打开一个打开TCP连接的站点可能会导致您的问题。为了摆脱它,你所能做的就是不同时下载很多东西(或者在不同的浏览器中下载,如果有必要的话)。
PS: The error net_error = -101 (ERR_CONNECTION_RESET) is not due to invalid headers, it is because of the timeout, waiting for some previous connection to the server to close.
PS:错误net_error = -101 (ERR_CONNECTION_RESET)不是由于头文件无效,而是由于超时,等待与服务器的一些先前连接关闭。
#2
9
Similar issue here and it appears that after a while, approx 3 minutes a socket chrome is trying to use is closed (I assume) by the OS.
类似的问题也出现了,过了一段时间,chrome尝试使用的插座大约3分钟就会被操作系统关闭(我猜)。
This is listed as a bug in the chromium forum as well. I'm guessing lack of some sort of "keep-alive" mechanism.: https://code.google.com/p/chromium/issues/detail?id=447463
这也是chromium论坛中的一个bug。我猜是缺少某种“维持生命”的机制。:https://code.google.com/p/chromium/issues/detail?id=447463
My error message is slightly different but it could be due to my application making the calls over SSL. Here's what I see in chrome://net-internals:
我的错误消息略有不同,但这可能是因为我的应用程序通过SSL进行调用。以下是我在chrome://net内部网中看到的:
First chrome finds an existing socket and the request is associated with it (HTTP_STREAM_JOB):
首先,chrome找到一个现有的套接字,请求与它关联(HTTP_STREAM_JOB):
t=1572 [st=0] HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION
--> source_dependency = 1347215 (HTTP2_SESSION)
t=1572 [st=0] HTTP_STREAM_JOB_BOUND_TO_REQUEST
--> source_dependency = 1348612 (URL_REQUEST)
t=1572 [st=0] -HTTP_STREAM_JOB
Then back in (URL_REQUEST) you will see it time out, note the 10 seconds lapse in time from t=1572 to t=11573:
然后返回(URL_REQUEST),你会看到它超时了,注意从t=1572到t=11573的10秒间隔:
t= 1572 [st= 0] HTTP2_SESSION_SEND_DATA
--> fin = true
--> size = 48
--> stream_id = 3
t= 1572 [st= 0] HTTP2_SESSION_UPDATE_SEND_WINDOW
--> delta = -48
--> window_size = 2147483551
t=11573 [st=10001] HTTP2_SESSION_CLOSE
--> description = "Failed ping."
--> net_error = -352 (ERR_SPDY_PING_FAILED)
Clearly there is a timeout when chrome attempts to adjust the window size on the existing socket. I assume this is due to inactivity on the socket.
显然,当chrome试图调整现有套接字上的窗口大小时,会出现超时。我认为这是由于套接字不活动造成的。
I'm going to try to implement some sort of heartbeat request at perhaps 60 sec interval to see if the issue still persists. I'll post an update with results.
我将尝试在大约60秒的间隔内实现某种心跳请求,看看这个问题是否仍然存在。我将更新结果。
UPDATE:
更新:
Added the following code to javascript that's loaded on every page. This is retrieving an empty html doc from the public root:
将以下代码添加到每个页面上加载的javascript中。这是从公共根目录检索空的html文档:
$(document).ready(function() {
$.keepalive =
setInterval(function() {
$.ajax({
url: '/ping.html',
cache: false
});
}, 60000);
});
This appears to have helped keep the socket open even with the sample below showing approx 6 minutes between "real" calls:
这似乎有助于保持插座打开,即使下面的示例显示在“真正的”调用之间大约6分钟:
At 570B per call in 60 sec intervals the ping call would add around 800kb of bandwidth usage per 24 hrs (per browser session). I'm not sure how much CPU overhead on the server this would cause.
每调用一次570B,每隔60秒,ping调用每24小时(每个浏览器会话)将增加大约800kb的带宽使用。我不确定这会在服务器上造成多少CPU开销。
For comparison, the BEFORE:
相比之下,前:
There has to be a better solution but i haven't been able to locate one yet.
必须有更好的解决方案,但我还没找到。