要求在镀铬中偶尔停滞很长时间

时间:2015-01-02 10:30:06

标签: javascript ajax google-chrome networking

Ajax请求偶尔会在Chrome中停滞很长时间。

如果有人能帮助我的话,我终于设法复制了它并保存了发布在这里所需的所有相关数据。

Chrome开发工具的时间线显示42.62秒的停止请求,如以下屏幕截图所示: enter image description here

并且在chrome://net-internals/#events(对于事件日志,请到最后)页面我发现最多的时间是由两个事件花费:

  • + HTTP_TRANSACTION_READ_HEADERS [dt = 21301]
  • + HTTP_TRANSACTION_READ_HEADERS [dt = 21304]

都获得ERR_CONNECTION_RESET

enter image description here

我认为错误是请求停滞了这么久的原因。

任何人都可以解释错误吗?

以下是请求的事件日志,我还将完整事件导出为json,您可以从here获取,然后在Chrome chrome://net-internals/#events页面内恢复。请注意请求网址是内部的,因此可能无法从公共网络访问:

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

编辑:相关问题 Issue 447463: Chrome-network: Long delay before RST message on stale sockets results in slow page loads.

2 个答案:

答案 0 :(得分:14)

我曾经遇到过类似的问题。问题的原因是每个浏览器都限制了到服务器的最大TCP连接数。对于chrome,限制为6。当您使用代理服务器时,问题更加突出,因为所有请求都是同一台服务器(代理服务器)。

Chrome不允许您更改此限制。事实上不应该这样。如果您想了解更多关于此限制存在的原因以及其他浏览器的限制,请阅读this article

此限制很少出现问题的原因是因为对同一主机的多个HTTP请求主要是连续发送,而不是并行发送,最好是通过相同的TCP连接发送。

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

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

  2. 多个持久连接已打开:如果您在代理服务器后面工作,则同时下载多个文件或打开保持TCP连接打开的网站可能是导致问题的原因。要摆脱它,你所能做的就是不要同时下载很多东西(或者在不同的浏览器中下载,如果你不得不这样做)。

  3. PS:错误 net_error = -101(ERR_CONNECTION_RESET)不是由于标头无效,而是因为超时,等待之前与服务器的某些连接关闭。

答案 1 :(得分:9)

这里有类似的问题,似乎经过一段时间后,操作系统关闭(我假设)套接字铬试用了大约3分钟。

这也被列为铬论坛中的一个错误。我猜测缺少某种"保持活力"机制。: https://code.google.com/p/chromium/issues/detail?id=447463

我的错误消息略有不同,但可能是由于我的应用程序通过SSL进行调用。这是我在chrome:// net-internals中看到的内容:

第一个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

然后回到(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)

显然,当chrome尝试调整现有套接字上的窗口大小时会出现超时。我认为这是由于套接字不活动。

我打算尝试以60秒的间隔执行某种心跳请求,看看问题是否仍然存在。我将发布带有结果的更新。

更新:

将以下代码添加到每个页面上加载的javascript中。这是从公共根目录中检索一个空的html文档:

    $(document).ready(function() {
        $.keepalive =     
                setInterval(function() {
                   $.ajax({
                      url: '/ping.html',
                      cache: false
                   });         
                }, 60000);    
    });

这似乎有助于保持插座打开,即使下面的示例显示在#34;真实"之间约6分钟。调用:

Result

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

为了比较,BEFORE:

Before changes

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