Javascript 请求偶尔在 chrome 中停滞很长时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27740692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:35:56  来源:igfitidea点击:

request stalled for a long time occasionally in chrome

javascriptajaxgoogle-chromenetworking

提问by Wayou

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: enter image description here

Chrome Dev Tool 的时间线显示请求停滞了 42.62 秒,如下面的屏幕截图所示: 在此处输入图片说明

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=21304]
  • +HTTP_TRANSACTION_READ_HEADERS [dt=21301]
  • +HTTP_TRANSACTION_READ_HEADERS [dt=21304]

both get ERR_CONNECTION_RESET.

都得到ERR_CONNECTION_RESET

enter image description here

在此处输入图片说明

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 herethen restore within the Chrome chrome://net-internals/#eventspage. note the request url is internal so maybe cant access from public network:

以下是请求的事件日志,我还将完整事件导出为 json,您可以从这里获取,然后在 Chromechrome://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 issueIssue 447463: Chrome-network: Long delay before RST message on stale sockets results in slow page loads.

编辑:相关问题问题 447463:Chrome 网络:过时套接字上的 RST 消息之前的长时间延迟导致页面加载缓慢。

回答by Tanmay

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:

如果您经常遇到此问题,那么原因可能是:

  1. 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.

  2. 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).

  1. 服务器不支持持久 TCP 连接:如果问题仅在访问特定服务器时出现,原因可能是 chrome 正在并行连接上获取多个资源(如图像、CSS 文件等)。由于在您的情况下,服务器位于您的本地网络上,您可能需要要求服务器管理员添加对持久 TCP 连接的支持。

  2. 打开多个持久连接:如果您在代理服务器后面工作,那么同时下载多个文件或打开保持 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)不是由于无效的标头,而是因为超时,等待某些先前与服务器的连接关闭。

回答by Marcin

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.

类似的问题在这里,似乎过了一会儿,大约 3 分钟后,操作系统关闭了(我假设)正在尝试使用的套接字 chrome。

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

这也被列为铬论坛中的错误。我猜缺少某种“保持活动”机制。: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-internals 中看到的:

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 分钟,这似乎有助于保持套接字打开:

Result

结果

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.

在 60 秒间隔内每次调用 570B 时,ping 调用将每 24 小时(每个浏览器会话)增加大约 800kb 的带宽使用量。我不确定这会导致服务器上多少 CPU 开销。

For comparison, the BEFORE:

为了比较,BEFORE:

Before changes

变更前

There has to be a better solution but i haven't been able to locate one yet.

必须有更好的解决方案,但我还没有找到。