本文前戏较多,务实的同学可以直接跳到结论。

由「钢的琴」网友脑洞大开延伸出了吉的他二的胡琵的琶,以及后来许嵩的「苏格拉没有底」,是否可以再拓展一下,得到哥本不爱吃哈根,哈根爱达斯等剧情乱入的关系。

上面跟本文要讨论的主题有什么关系?

没关系。

缘起

有用户反馈内部MIS系统慢,页面加载耗时长。前端同学们开组会提及此事,如何解决慢的问题。

最致命的是:偶发!你不能准确知道它抽风的时间点,无法在想要追查问题的时候必现它。
这只是一方面,另外,慢的可能实在太多了,那么问题来了,是前端导致的还是后端的问题?

对慢的定义也有待商榷,多久算慢?如果这个页面加载大量数据耗时增加那我认为这是正常的。但这个时限超过了一个合理的自然值,就变得不那么正常了,比如四五十秒,一分多钟。

最奇葩的是,如此久的耗时居然不会报超时错误,而是拿到正确返回后将页面呈现了出来!

可能的原因

初步猜测

初步的猜测可能是后端迟迟未返回造成浏览器处于等待状态。这个猜测是很合乎逻辑的,至少能够很合理地解释Chrome Dev Tool 网络面板中我们看到的状态pending
041058318722560.jpg

但我们不能停留在猜测阶段,要用事实说话,数据才不会骗人。这也正是本文将要展开的。

下面是另外一些被提出来的可能性。

Angular

Angular首当其冲。为什么,因为这个问题出现在后台MIS系统中,且这些系统多用Angular开发。

Angular :怪我咯。

因为问题多出现在基于Angular的MIS系统中,并且Angular的性能一直是被诟病的,所以听到不少的声音将矛头指向Angular。这似乎没什么好庇护的。Angular在整个项目中的前端部分扮演了很重的角色。树大招风,理所当然。

这让我想起初次接触到这个问题时,那是在七月份,芙蓉的爱马仕平台用户反馈了慢的问题,报到前端,顺便看了下,一看Pending状态,觉得是后端未返回。只是情深缘浅当时也没有深入,同时洪堂大神负责去追查了。当时那个系统,很负责地说,没有用Angular。

所以这里可以为Angular正身,将其排除。

内部封装的commonResource

内部对Angular原生的resource进行了封装,做了些数据的转换处理。既然上面Angular都被正身了,那么这里的怀疑也是站不住脚的。

Chrome插件

经查,网上好多呼声有说是Adblock等与网络有关的Chrome插件。可我不使用它已经很多年,那玩意儿太重,后来找到了算法更高级体量更轻便的µBlock。关键是后者也在我使用一段时间后放弃了,因为个人觉悟提高了,免费内容是需要广告支撑的,如果你不希望付费变成强制的话。所以现在一直是处于未开这类插件的状态。那么在未开广告屏蔽插件的情况下重现了问题,可以排除这类插件的影响了。

关于插件,此刻我的Chrome里唯一还会接管Chrome网络的便是代理插件SwitchSharp, 升级之后这货叫Switchy哦卖喝(与时俱进的我当然使用的是后者)。

Chrome独家?

因为内部MIS只兼容了Chrome开发,所以不会有在除了Chrome之外的浏览器上使用的场景,并且其他浏览器上面追查问题也是很痛苦的事情。这里仅在火狐里进行了少量尝试,未复现。同时接到反馈,Safari里也未复现。但也不能肯定就只有Chrome存在问题。似乎这个对于问题的解决还不那么重要,所以先不管。

杀毒软件

后面会看到,在追查错误号ERR_CONNECTION_RESET时引出了杀毒软件可能会导致Chrome工作不正常的情况,但这个可能也在稍后被排除人。

并且,我厂使用Mac的同学并没有安装杀软,依然是可以复现的。

重现

第一件事情便是重现。虽然是偶发,为了尽可能保存现场,还是想要手动将它刷出来。天不灭我,经过良久尝试,该问题被复现。于是各种截图,保存请求数据。这个时候还没有开启chrome://net-internals/#events页面来捕获事件日志。

为以后引用方便,这里留下版本信息:

OS: Windows 7 Ultimate
Chrome:Version 39.0.2171.95 m

这是请求Pending时的请求信息:
041058499506204.jpg

这是请求成功返回后:
041059026842280.jpg

可以看到Stalled了1分多钟。神奇的是竟然不报超时错误而是成功返回了。

同时保存了请求头,响应头,还将本次问题请求保存成了CURL等。现场已经留下,感觉Bug不会存活太久了。

接下来就是对比正常请求跟这次异常请求的不同,一轮比较下来,未发现多少异常。

常态与变态的对比

请求头对比:

请求头的对比已丢失,但除了时间外,其余无差别。

响应头对比:
041059139196315.jpg

返回结果对比:
041059229818278.jpg

上面的对比意义不大,但还是要做的,万一发现有价值的情报了呢。

一次失败的尝试

解决问题时,习惯性地看有没有人已经碰过到类似问题,这样做的好处很明显:
如果有,站在巨人的肩上轻松地牛逼着;
如果没有,这是个机会。

于是信心满满地出发了,因为根据一条互联网准则,70%的问题已经有人解决过了,那些没有被解决的要么是现有技术达不到,要么是未被人发现。所以能够搜索出问题答案的概率还是蛮大的。

经过旷日持久的搜索,有价值的参考寥寥无几。可能是问题本身太过奇葩,遇到的人太少;也有可能问题过于晦涩,无法表述;抑或我搜索的关键词不够精准。
倒也不是说一个都没找到,但一般涉及网络日志的情况就无人问津了,无人问津了!

比如这个,一年多前被人问的,现在还没有一个回答。

还比如这个

Chrome stalls when making multiple requests to same resource?

是后来作为参考的,也是无人问津了……

甚至自己也去问了一个,依然无人问津了……

神秘的CACHE LOCK

上面提到,Stackoverflow上找到一个问题,跟现在需要解决一有些类似点:

  • 偶发,并不是必然出现的。这里我们的问题也是偶发,很难复现,需要反复刷。
  • 也是请求被Pending了很久,从请求的时间线来看,体现在Stalled上。

这一刻,有一种感觉大概是这样的:

伟大的意大利的左后卫!他继承了意大利的光荣的传统。法切蒂、卡布里尼、马尔蒂尼在这一刻灵魂附体!格罗索一个人他代表了意大利足球悠久的历史和传统,在这一刻他不是一个人在战斗,他不是一个人!

突然看到了希望。该提问到没有给出什么建设性的意见,但它后面的追加编辑却给出了答案。过程是查看Chrome的网络日志,在事件里面发现有一个超时错误:

t=33627 [st= 5] HTTP_CACHE_ADD_TO_ENTRY [dt=20001]
--> net_error = -409 (ERR_CACHE_LOCK_TIMEOUT)

耗时20秒之久!而且写得非常明显是ERR_CACHE_LOCK_TIMEOUT。根据提问者贴出来的链接,了解到Chrome有一个缓存锁的机制。

具体源于一个今年6月分实现的一个补丁,加入了这么个机制,而这个机制的引入又源于2010年的一个issue。具体信息可以通过这个这里查看,下面引用如下。

Basically here is the situation:

The site author has a long-lived XHR being used to stream a slow response from the server. This XHR response is cachable (it is just really slow). They kick off the XHR asynchronously, and as data slowly arrives on it, update the progressive load of the webpage. Cool.

Now what happens if you try to load this page in multiple tabs of Chrome is:
The first page starts to load just fine, but the second one does nothing.
What has happened, is the background XHR of the first page load has acquired an exclusive lock to the cache entry, and the background XHR of the second page is stalled at "Waiting for cache..." trying to get a reader access to the cache entry.

Since the first request can takes minutes, this is a problem.

eroman 同学指出了这么一个事实:

浏览器对一个资源发起请求前,会先检查本地缓存,此时这个请求对该资源对应的缓存的读写是独占的。那么问题来了,试想一下,当我新开一个标签尝试访问同一个资源的时候,这次请求也会去读取这个缓存,假设之前那次请求很慢,耗时很久,那么后来这次请求因为无法获取对该缓存的操作权限就一直处于等待状态。这样很不科学。于是有人建议优化一下。也就是上面所描述的那样。

随着问题的提出,还出了两种可能的实现方案。

(a) [Flexible but complicated] Allow cache readers WHILE writing is in progress. This way the first request could still have exclusive access to the cache entry, but the second request could be streamed the results as they get written to the cache entry. The end result is the second page load would mirror the progress of the first one.

(a) [Naive but simpler] Have a timeout on how long we will block readers waiting for a cache entry before giving up and bypassing the cache.

我猜上面第二个(a)应该是(b)。简单说第一种优化方案更加复杂但科学。之前的请求对缓存仍然是独占的,但随着前一次请求不断对缓存进行更新,可以把已经更新的部分拿给后面的请求读取,这样就不会完全阻塞后面的请求了。

第二种方案则更加简单暴力。给后来的请求设定一个读取缓存超时的时限,如果超过了这个时限,我认为缓存不可用或者本地没有缓存,忽略这一步直接发请求。

于是Chromium的开发者们选择了后者简单的实现。也就是Issue 345643003: Http cache: Implement a timeout for the cache lock 这个提交里的实现。

这个提交的描述如下:

The cache has a single writer / multiple reader lock to avoid downloading the same resource n times. However, it is possible to block many tabs on the same resource, for instance behind an auth dialog.

This CL implements a 20 seconds timeout so that the scenario described in the bug results in multiple authentication dialogs (one per blocked tab) so the user can know what to do. It will also help with other cases when the single writer blocks for a long time.

The timeout is somewhat arbitrary but it should allow medium size resources to be downloaded before starting another request for the same item. The general solution of detecting progress and allow readers to start before the writer finishes should be implemented on another CL.

于是就产生了上面题主遇到的情况。

所以他的解决方法就很明朗了,对请求加个时间戳让其变得唯一,或者服务器响应头设置为无缓存。Both will work!

那么我们的问题也会是这样的么?我幻想由于某种未知的原因造成之前的请求不正常(虽然网络面板里没有数据证明这样的阻塞请求在问题请求之前存在),然后我们的MIS里打开页面时读取不到缓存,卡了,一会儿缓存好了,正常了,于是在等待了几十秒后请求成功发出去了。

似乎不太可能。因为恰好内部MIS系统的响应头里已经加了缓存控制了 Cache-Control: no-cache

以下是一次问题请求的响应头:

HTTP/1.1 200 OK
Date: Wed, 31 Dec 2014 11:47:21 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Cache-Control: no-cache
tracecode: 28410188240979065866123119
tracecode: 28410188240506537994123119
Server: Apache

并且开多个标签也是无法进行有效重现的。

因此可以排除缓存的干扰。那么似乎这里的缓存锁并不是导致问题的原因,只能另寻他路。不得不说,高兴过后有点失望。

八卦时间

可喜的是,在细细口味了上面缓存机制引入的过程后,真是耐人寻味。这里不妨八卦一下。相信你也注意到了,上面提到,该缓存问题的提出是在2010年,确切地说是Jun 8, 2010。是的,2010年6月8日由eroman 同学提出。但最后针对该问题进行修复的代码提交却是在今年6月份,2014年6月24日,提交时间摆在那里我会乱说?
041059454502648.jpg

于是好奇为什么会拖了这么久,遂跟了一下该问题下面的回复看看发生了什么。简直惊呆了。

  • 同月14号,有了首次对这个问题的回复,那是将该问题指派给了rvargas同学。

  • 一个月过去了,也就是7月15号,rvargas同学指出了与该问题关联的另外一个issue「issue 6697」

  • 接下来是8月5日,rvargas同学为该问题贴上了标签-Mstone-7 Mstone-8,表明将会在里程碑7或者8里面进行修复。但在后面的10月7日,这个日程又被推到了-Mstone-8 Mstone-9

  • 再接下来11月5日,有人表示以目前的速度及bug数量,还没有时间来修复它,重点在处理优先级为p1的问题上。于是此问题又成功被顺延了,来到-mstone-9 Mstone-10,同时优级降为p2。Chromium人手也不够啊,看来。

  • 时间来到12月9日,因为优先级为p2的issue如果没有被标为开始状态的话又自动推到下一个里程碑了,于是顺利来到 -Mstone-10 MovedFrom-10 Mstone-11。次年2月来到-Mstone-11 Mstone-12。完成了一次跨年!

…………

  • 上面省略N步。如此反复,最后一次被推到了-Mstone-16,那是在2011年10月12日。

  • 时间一晃来到2013年,这一年很平静,前面的几个月都没有人对此问题进行回复。直到11月27日,有人看不下去了,评论道:

This bug has been pushed to the next mstone forever...and is blocking more bugs (e.g https://code.google.com/p/chromium/issues/detail?id=31014)and use-cases same video in 2 tags on one page, and adaptive bit rate html5 video streaming whenever that will kick in. Any chance this will be prioritized?

由于这个bug的无限后延也阻塞了另外一些同类问题,看来是时候解决了。这不,最初的owner 当天就进行了回复:

ecently there was someone looking at giving it another try... I'd have to see if there was any progress there.

If not, I may try to fix it in Q1.

最后一句亮瞎。敢情这之前owner就没有想过要去真正解决似的,因为有其他人在看这个问题了,所以就没管了,如果Q1还没人解决的话,我会出手的!嗯,就是这个意思。

…………

最后,也就是上文提到的,2014年6月,还是rvargas同学对这个问题进行了修复,实现了对缓存读取20秒超时的控制。

该问题就是这样从2010来到2014的。我怀疑Chrome是如何成为版本帝的。

阶段总结

仅有的希望到此似乎都没有了。不过前面的努力也不是没有作何收获,至少我得到了以下有价值的信息:

  • 谷歌的神坛光环不再那么耀眼,他们的产品也是有Bug的
  • Chrome 处理issue的效率,当然不排除这种大型项目bug数量跟人力完全不匹配的情况
  • 受上面Stackoverflow问题的启发,接下来我将重点转移到了针对出问题请求的日志分析上,并且取得了突破

开始新的征程

虽然上面的努力没能定位到问题,但作为这次对解决这次问题的尝试,还是将它记录了下来,估且称作「旧的回忆」吧。

下面开始「新的征程」。

041100027312935.jpg

再次重现

这次受到上面的启发,开启chrome://net-internals/#events页面来捕获事件日志。看是否有错误或异常发生。

再次经过旷日持久的机械操作,重现了!这次,日志在手,天下我有。感觉Bug不会存活多久了。

Chrome Dev Tools 网络面板截图:
041100206843850.jpg

由上面的截图看到,本次出问题的请求总耗时42.74秒。

问题请求的时间线信息截图:
041100140444713.jpg

可以预见,通过捕获的日志完全可以看到Stalled那么久都发生了些什么鬼。

话不多说,切换到事件捕获页面,定位到出问题的请求,查看其详情。同时将该日志导出,永久保存!作为纪念,也方便以后再次导入查看。有兴趣的同学可以访问下方下载后进行导入,就可以清晰地查看到现场了,就好像你亲历了整个犯罪现场一样。

日志还原

  • 下载该日志文件

  • 在Chrome新开一个标签输入chrome://net-internals/#events
  • 切换到Import,选择刚才下载的JSON文件进行导入
  • 切换到Events,定位到http://qa.tieba.baidu.com/release/getReleaseHistory?projectId=fum1.0.593 这个请求

此刻右边出现的便是该问题请求的详细日志。

日志解读

下面不妨把日志文件贴出来先:

193486: URL_REQUEST
http://qa.tieba.baidu.com/release/getReleaseHistory?projectId=fum1.0.593
Start Time: 2015-01-02 17:51:05.323t=    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.1Host: qa.tieba.baidu.comConnection: keep-aliveAccept: 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.36Referer: http://qa.tieba.baidu.com/project/Accept-Encoding: gzip, deflate, sdchAccept-Language: en-US,en;q=0.8Cookie: [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.1Host: qa.tieba.baidu.comConnection: keep-aliveAccept: 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.36Referer: http://qa.tieba.baidu.com/project/Accept-Encoding: gzip, deflate, sdchAccept-Language: en-US,en;q=0.8Cookie: [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.1Host: qa.tieba.baidu.comConnection: keep-aliveAccept: 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.36Referer: http://qa.tieba.baidu.com/project/Accept-Encoding: gzip, deflate, sdchAccept-Language: en-US,en;q=0.8Cookie: [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 OKDate: Fri, 02 Jan 2015 09:51:48 GMTContent-Type: application/json; charset=UTF-8Transfer-Encoding: chunkedConnection: keep-aliveCache-Control: no-cachetracecode: 31079600320335034634010217tracecode: 31079600320537995786010217Server: 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

首先,日志显示的总耗时与上面网络面板截图的总耗时是吻合的,都是42.74秒,说明我们定位正确。

以下时间均以毫秒计

日志第一列为时间线,自请求发起时算。
第二列为每步操作所逝去的时间,时间差的概念,与第三列里面的dt不同,它会积累前面的耗时。
第三列为具体的事件,以及相应事件的耗时dt,此耗时为绝对耗时。

+号对应事件开始,-号对应事件结束,也就是说他们必然成对出现。住里是展开后更加详细的子事件。直到不能再细分。

如果说一开始接触到这个日志时手足无措的话,我们来看一下正常情况下的日志是怎样的,有对比才有发现。

以下随便摘取一次正常请求的日志,如下:

384462: URL_REQUEST
http://qa.tieba.baidu.com/release/getReleaseHistory?projectId=fum1.0.593
Start Time: 2015-01-03 20:23:54.698t=1556 [st=  0] +REQUEST_ALIVE  [dt=172]
t=1556 [st=  0]    URL_REQUEST_DELEGATE  [dt=0]
t=1556 [st=  0]   +URL_REQUEST_START_JOB  [dt=171]--> load_flags = 335609856 (BYPASS_DATA_REDUCTION_PROXY | MAYBE_USER_GESTURE | VERIFY_EV_CERT)--> method = "GET"--> priority = "LOW"--> url = "http://qa.tieba.baidu.com/release/getReleaseHistory?projectId=fum1.0.593"
t=1557 [st=  1]     +URL_REQUEST_DELEGATE  [dt=4]
t=1557 [st=  1]        DELEGATE_INFO  [dt=4]--> delegate_info = "extension Tampermonkey"
t=1561 [st=  5]     -URL_REQUEST_DELEGATE
t=1561 [st=  5]      HTTP_CACHE_GET_BACKEND  [dt=0]
t=1561 [st=  5]      HTTP_CACHE_OPEN_ENTRY  [dt=1]--> net_error = -2 (ERR_FAILED)
t=1562 [st=  6]      HTTP_CACHE_CREATE_ENTRY  [dt=0]
t=1562 [st=  6]      HTTP_CACHE_ADD_TO_ENTRY  [dt=0]
t=1562 [st=  6]      URL_REQUEST_DELEGATE  [dt=0]
t=1562 [st=  6]     +HTTP_STREAM_REQUEST  [dt=2]
t=1564 [st=  8]        HTTP_STREAM_REQUEST_BOUND_TO_JOB--> source_dependency = 384467 (HTTP_STREAM_JOB)
t=1564 [st=  8]     -HTTP_STREAM_REQUEST
t=1564 [st=  8]     +HTTP_TRANSACTION_SEND_REQUEST  [dt=1]
t=1564 [st=  8]        HTTP_TRANSACTION_SEND_REQUEST_HEADERS--> GET /release/getReleaseHistory?projectId=fum1.0.593 HTTP/1.1Host: qa.tieba.baidu.comConnection: keep-aliveAccept: 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.36Referer: http://qa.tieba.baidu.com/project/Accept-Encoding: gzip, deflate, sdchAccept-Language: en-US,en;q=0.8Cookie: [2642 bytes were stripped]
t=1565 [st=  9]     -HTTP_TRANSACTION_SEND_REQUEST
t=1565 [st=  9]     +HTTP_TRANSACTION_READ_HEADERS  [dt=161]
t=1565 [st=  9]        HTTP_STREAM_PARSER_READ_HEADERS  [dt=160]
t=1725 [st=169]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS--> HTTP/1.1 200 OKDate: Sat, 03 Jan 2015 12:23:54 GMTContent-Type: application/json; charset=UTF-8Transfer-Encoding: chunkedConnection: keep-aliveCache-Control: no-cachetracecode: 14346880480340800522010320tracecode: 14346880480253893130010320Server: Apache
t=1726 [st=170]     -HTTP_TRANSACTION_READ_HEADERS
t=1726 [st=170]      HTTP_CACHE_WRITE_INFO  [dt=0]
t=1726 [st=170]      HTTP_CACHE_WRITE_DATA  [dt=0]
t=1726 [st=170]      HTTP_CACHE_WRITE_INFO  [dt=0]
t=1726 [st=170]     +URL_REQUEST_DELEGATE  [dt=1]
t=1726 [st=170]        DELEGATE_INFO  [dt=1]--> delegate_info = "extension Tampermonkey"
t=1727 [st=171]     -URL_REQUEST_DELEGATE
t=1727 [st=171]   -URL_REQUEST_START_JOB
t=1727 [st=171]    URL_REQUEST_DELEGATE  [dt=0]
t=1727 [st=171]    HTTP_TRANSACTION_READ_BODY  [dt=0]
t=1727 [st=171]    HTTP_CACHE_WRITE_DATA  [dt=1]
t=1728 [st=172]    HTTP_TRANSACTION_READ_BODY  [dt=0]
t=1728 [st=172]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1728 [st=172] -REQUEST_ALIVE

针对上面正常的请求,我们主要关注两部分,如下面的截图:

  • 发送请求头 +HTTP_TRANSACTION_SEND_REQUEST [dt=1]
  • 读取响应头 +HTTP_TRANSACTION_READ_HEADERS [dt=161]

041100388881222.jpg

这是正常的情况下,没有什么问题。并且日志里可以清晰地看到发送的请求头是什么,然后解析出来的响应头是什么。这跟在网络面板看到的是一致的。

再回到出问题的请求日志上来,同样我们只关注这两部分。如下面的截图:

041100487947230.jpg

与正常相比,最后一次发送请求和读取响应头无异常,时间就多在了前面还有再次发送和请求的过程,细看时间都花在了以下两个事件中:

  • HTTP_STREAM_PARSER_READ_HEADERS [dt=21301]
  • HTTP_STREAM_PARSER_READ_HEADERS [dt=21304]

该事件的名称已经自我解读,意思是解析读取的响应头。但问题是紧接着下面报错了,

--> net_error = -101 (ERR_CONNECTION_RESET)

读取响应头时发生了链接重置的错误,有理由认为本次链接是不成功的,没拿到正确的响应头,于是解析不成功。时间都花在了这里,足足21秒之久,两个21秒造就了上面看到的Stalled了42秒之久。

问题似乎已经很明朗了。链接被重置。

在第三次尝试的时候正常了,于是正确返回,我们才看到了被解析的响应头被展示在了下面。也就是说在出问题的时候要么响应头未拿到,要么响应头非法导致解析不成功。而原因就是链接被重置。

那么接下来的工作就是对ERR_CONNECTION_RESET这个错误的追查了。

官方关于 ERR_CONNECTION_RESET 错误的解释

未找到官方相应的资料,Chrome官网上唯一关于此错误的描述是在安装Chrome时出现Error 101。我估计文档的撰写人员没想到谁会这么蛋疼想要看这些生涩的东西,除了开发者。既然你都是开发者了,那为什么不去看Chromium的源码。

好吧,唯一的途径似乎只能从源码中寻找了。作为只精JS的前端人员,现在要从C,C++代码中找答案了。估计追完这个问题,我会尝试为Chromium贡献代码。

慢着,在这之前,还是搜到一些关于这个错误的信息的。但似乎都不怎么靠谱。

比如这里提到,是因为ISP网络问题,实在无太可能。还有这是神马居然一个硬件网站但提到了这个错误,并且怀疑是杀软导致Chrome出问题,但杀软已经在上文被我们排除了。

Chromium 源码

那么这个错误究竟是什么。能不能找到点靠谱的解释。当然能,让我们进入到Chromium的源码中去。

ERR_CONNECTION_RESET被唤起的地方

在Chromium的源码中搜索该常量名,确实出现很多结果。联系到我们查看日志发现问题的上下文,是在解析响应头报的。所以我们定位到http_stream_parser.cc文件,同时注意到有一个文件叫net_errors_win.cc,所以猜测他是定义所有错误常量用的,也顺便打开之。

经过观察src/net/base/net_errors_win.cc 其路径和代码得知其中多为系统级别的错误,似乎跟我们的问题不是很关联,忽略该文件。

source.jpg

http_stream_parser.cc文件中,ERR_CONNECTION_RESET仅出现一次。这给我们定位带来了极大的便利。

cpp [chromium]//src/net/base/net_errors_win.cc https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_stream_parser.cc&q=ERR_CONNECTION_RESET&sq=package:chromium&dr=C http_stream_parser.cc // Returns true if |error_code| is an error for which we give the server a // chance to send a body containing error information, if the error was received // while trying to upload a request body. bool ShouldTryReadingOnUploadError(int error_code) { return (error_code == ERR_CONNECTION_RESET); }

这里定义了一个ShouldTryReadingOnUploadError 的方法,注释耐人寻味,这个时候,这样的情景,能否正确解读注释成为了比读懂代码更重要(这是我在看JS代码时永远无法体味到的感觉),下面尽可能对它进行理解:

在尝试发送一个请求体的时候,让服务器尝试发送一个带错误的响应体,如果我们接收到了该错误则返回true

我承认被上面的复杂从句打败!

那么我们来看这个方法被调用的场景。

现在我们点击上面的ShouldTryReadingOnUploadError方法,代码下方出现调用了该方法的地方,一共有两处。

041101040595632.jpg

分别点击进行查看。

cpp 459行DoSendHeadersComplete方法里进行了调用 int HttpStreamParser::DoSendHeadersComplete(int result) { if (result < 0) { // In the unlikely case that the headers and body were merged, all the // the headers were sent, but not all of the body way, and |result| is // an error that this should try reading after, stash the error for now and // act like the request was successfully sent. if (request_headers_->BytesConsumed() >= request_headers_length_ && ShouldTryReadingOnUploadError(result)) { upload_error_ = result; return OK; } return result; }

虽然不太可能,但也不排除头部和请求体合并的情况,当所有头部发送完毕,请求体不一定,此时result便是需要稍后处理的一种错误,这里暂且先返回OK

cpp 516行另一个DoSendBodyComplete方法里进行了调用 int HttpStreamParser::DoSendBodyComplete(int result) { if (result < 0) { // If |result| is an error that this should try reading after, stash the // error for now and act like the request was successfully sent. if (ShouldTryReadingOnUploadError(result)) { upload_error_ = result; return OK; } return result; }

跟上面类似,如果result出错,稍后处理,先返回正常

这也与我们在日志中看到的情况相符,在前面再次错误后,这次请求并没有终止结束,而是尝试到了第三次并且以成功结束的。

但不管怎样,从这两个方法,一个DoSendHeadersComplete, 另一个DoSendBodyComplete,身上能体现出请求确实已经发出去。

TCP RST

另外,在net_error_list.h这个文件的109行,可以准确找到我们在日志中得到的101号错误。它的定义如下:

// A connection was reset (corresponding to a TCP RST).
NET_ERROR(CONNECTION_RESET, -101)

从括号中的进一步解释可以知道,它代表TCP连接重置。

TCP

那么问题来了,什么是TCP连接重置?什么会引发TCP连接重置。从这篇文章中有比较详细的解答。

想要完全解释,本文似乎是不可能的了。但根据上面的文章,这里可以简单转述一下。

什么是TCP连接

它是一种协议。当网络上一个节点想与另一个节点通信时,双方需要选建立连接。而这个连接过程需要大家都懂的一种约定,TCP就是事先定好的一种约定,于是我们采用它吧,于是其中一个节点按照这个约定发起一建立连接的请求,另一节点收到后,根据该约定,便能读懂这个请求里各字段的意思:哦,丫这是想约我呢。

三次握手

继续上面的例子。A想与B通信,并且使用TCP。

首先A发起一个报文,其中包含自己的地址,想要连接的目标地址,自己用来连接的端口及目标机器的端口,etc.

B收到邀约,并且愿意付约。此刻B需要回传一个报文,告诉A我愿意跟你连接。

A收到B的肯定应答,到此A与B经历了三次通信或者说是握手,双方都没有异议,连接建立。

而连接断开的过程也颇为类似。双方中的一方比如说A先发起一个断开连接的报文FIN,B收到并确认,然后回传一个可以断开的报文FIN给A。此刻A收到并确认。此刻双方都确认后,连接可以安全断开,但还会保持一个等待断开的状态,大概持续4分钟,用于之前连接通路上未传输完成的数据进行善后。

什么是重置

上面提到了4分钟的等待时间,而重置RESET便是立即断开连接的手段。

发生重置的情况

到此重置的作用已然明了。也就是说,重置甚至算不上一个错误,它是TCP连接中的一种正常情况。但什么时候会发生重置,如何引起的。

上文列出了三种情况。

SMB Reset

简单举例来说,服务器提供了两个端口445,139进行服务,客户端同时去请求与这两个端口连接,服务器返回了两个端口可以被连接,此刻客户端择优选择一个进行连接,而重置另一个。

Ack, Reset

报文重置发生主要有以下情况:

  • 服务器没有监听被请求的端口,无法建立连接
  • 服务器此刻无法比如没有充裕的资源用来连接连接

TCP Reset due to no response

由于没有响应而被重置。当发起连接的一方连续发送6次请求未得到回应,此刻默认他们之间已经通过三次握手建立了连接并且通信有问题,发起的一方将连接重置。

Application Reset

除了上面的情况,找不到TCP内部自己发送的重置,则归为了这一类。程序内将连接重置。此种情况包含了所有你想得到想不到将连接断开的情况。有可能是程序内部逻辑重置的,所以不能完全认为此时发生了错误。

值得注意的是,上面列出的情况服务器的不确定性导致连接重置的可能性要合理些。Chrome 主动发起URL请求不太可能自己又重置掉,并且没有理由重置掉后又去重连。

Chrome Dev Tool 中时间线各阶段代表的意义

另附注一下Chrome Dev Tool 中请求的时间线各阶段代表的意义。
以下内容扒自Chrome 开发者文档页,然后我将它本地化了一下下。

041101226069432.png

Stalled/Blocking

在请求能够被发出去前的等等时间。包含了用于处理代理的时间。另外,如果有已经建立好的连接,那么这个时间还包括等待已建立连接被复用的时间,这个遵循Chrome对同一源最大6个TCP连接的规则。

「拿我们的情况来说,上面出错所有的耗时也是算在了这部分里面。网络面板中显示的其余时间比如DNS查找,连接建立等都是属于最后那次成功请求的了」

Proxy Negotiation

处理代理的时间。

DNS Lookup

查找DNS的时间。页面上每个新的域都需要一次完整的寻路来完成DNS查找。

Initial Connection / Connecting

用于建立链接的时间,包括TCP握手及多次尝试握手,还有处理SSL。

SSL

完成SSL握手的时间。

Request Sent / Sending

Time spent issuing the network request. Typically a fraction of a millisecond.

发起请求的时间,通常小到可以忽略。

Waiting (TTFB)

等待响应的时间,具体来说是等待返回首个字节的时间。包含了与服务器之间一个来回响应的时间和等待首个字节被返回的时间。

Content Download / Downloading

用于下载响应的时间

结论

我相信很多同学是直接跳到这里来了的。事实上我给不出什么解决方案,只能证明前端代码没有问题,请求已发。请RD同学接着排查。

另外,利用好Chrome的内部网络日志chrome://net-internals/#events进行网络分析是个非常好的选择,特别是在处理这些调试面板上无法体现的细节问题时。

参考及引用

#1 Chrome stalls when making multiple requests to same resource?
#2 What does “pending” mean for request in Chrome Developer Window?
#3 Evaluating network performance / Resource network timing
#4 Provisional headers are shown
#5 “CAUTION: provisional headers are shown” in Chrome debugger
#6 Chrome 里的请求报错 "CAUTION: Provisional headers are shown" 是什么意思?
#7 Issue 345643003: Http cache: Implement a timeout for the cache lock
#8 Issue 46104: Pages can get blocked in "Waiting for Cache" for a very long time
#9 Providing Network Details for bug reports
#10 从FE的角度上再看输入url后都发生了什么
#11 ERR_CONNECTION_RESET 的Chromium 源码
#12 Chromium Network Stack
#13 Where do resets come from? (No, the stork does not bring them.)

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 教你如何用Angular更好地管理RxJS订阅

    全文共2792字&#xff0c;预计学习时长13分钟 图源&#xff1a;unsplash 在一个Angular组件内处理多个可观察对象的RxJS&#xff0c;需要在某个地方订阅它们&#xff0c;更重要的是&#xff0c;当不再需要时可以取消订阅。 有成千上万的文章告诉我们&#xff0c;经常退订是多么…...

    2024/4/20 16:34:49
  2. angularjs 取消/中止 ajax请求

    解决方法非常简单&#xff0c;即为我们发出的$http设置一个timeout: 这里我们需要借助另一个promise. //创建中止请求控制的promise let end $q.defer(); //监听取消上传动作 $scope.$watch(cancel,() > {if(cancel){end.resolve();} } ) this.$http.post(http://www.xxx.co…...

    2024/4/21 12:11:34
  3. 长沙双眼皮价格w可丨靠.半岛

    ...

    2024/4/21 12:11:33
  4. 长沙双眼皮多少钱w可丨靠.半岛

    ...

    2024/4/21 12:11:33
  5. 长沙割双眼皮手术 前丨往.半岛

    ...

    2024/4/21 12:11:31
  6. angularJS 判断是否数字

    angular.isNumber 转载于:https://www.cnblogs.com/mkxzy/p/7412439.html...

    2024/4/21 12:11:30
  7. 南昌做双眼皮??约同济

    ...

    2024/4/21 12:11:29
  8. 什么叫组件化开发?

    作者&#xff1a;aloo链接&#xff1a;https://www.zhihu.com/question/29735633/answer/90873592来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。从第一代码农写下第一行代码开始到上个世纪的80年代的软件危机&#xff…...

    2024/4/21 12:11:29
  9. 牛人的技术博客

    GET POST 区别详解_HTML/Xhtml_网页制作_脚本之家-www.jb51.net/web/12714.html RunJS 广场&#xff0c;最新最热代码展示-runjs.cn/square/hot?p9 JavaScript MVC框架PK&#xff1a;Angular、Backbone、CanJS与Ember-CSDN.NET-www.csdn.net/article/2013-04-25/2815032-a-com…...

    2024/4/21 12:11:28
  10. 前端MVC框架Backbone 1.1.0源码分析(一)

    前言 如何定义库与框架 前端的辅助工具太多太多了&#xff0c;那么我们是如何定义库与框架&#xff1f; jQuery是目前用的最广的库了&#xff0c;但是整体来讲jQuery目的性很也明确针对“DOM操作”&#xff0c;当然自己写一个原生态方法也能实现同样的DOM操作&#xff0c;换句话…...

    2024/4/21 12:11:26
  11. JavaWeb开发技术学习笔记(一)—— 整体框架介绍

    JavaWeb开发技术 最近正在学习JavaWeb开发,会持续分享一些个人的笔记,供有需要的人一起借鉴参考,有什么问题欢迎在评论区进行交流。 JavaWeb学习框架以及思维导图:概念、技术体系 ​ JAVA WEB、java语言 网页 静态内容–在客户端运行–前端开发技术 动态内容–在服务器上获…...

    2024/4/21 12:11:25
  12. 进阶攻略|最全的前端开源JS框架和库

    新的 Javascript 库层出不穷&#xff0c;从而Web 社区愈发活跃、多样、在多方面快速发展。详细去描述每一种主流的 Javascript框架和库近乎不可能&#xff0c;所以在这篇文章中主要介绍一些对前端发展最具影响力的前端框架。接下来让我们来共同研究一些主流前端框架、库和工具&…...

    2024/4/21 12:11:24
  13. 重庆双眼皮整形哪里好真优1星宸

    ...

    2024/4/21 12:11:23
  14. 利用avalon 实现一个简单的成绩单

    利用avalon 实现一个简单的成绩单 本文的灵感是来自Halower的这篇博文&#xff0c;他是使用knockout与jQuery实现的。不过我觉得MVVM本来就强大的事件绑定功能&#xff0c;因此用jQuery 是多此一举。另&#xff0c;他也用了一些面向对象的写法。我个人认为&#xff0c;纯数据就…...

    2024/4/20 16:35:12
  15. 什么叫组件化开发

    转载&#xff1a;什么叫组件化开发? - aloo的回答 - 知乎 https://www.zhihu.com/question/29735633/answer/90873592 从第一代码农写下第一行代码开始到上个世纪的80年代的软件危机&#xff0c;码农一直在考虑一个问题&#xff0c;怎么让写代码容易。抛开找大牛&#xff0c;…...

    2024/4/20 16:35:12
  16. 再见JQuery,我的老朋友

    免责声明 本文是仓促之作&#xff0c;从构思到成文不足半天。文中没有提到很多优秀的库和框架&#xff0c;提前在此致歉&#xff0c;因为没时间搜集整理。但这不代表笔者对这些库和框架没有敬意。实际上&#xff0c;包括jQuery在内&#xff0c;我的敬意是给这些名字背后整个社区…...

    2024/4/20 16:35:11
  17. STF创业团队面试准备

    为什么80%的码农都做不了架构师&#xff1f;>>> 然后今天接到一个创业团队的电面。 要求&#xff1a;了解angularJS&#xff0c;熟悉MVC&#xff0c;以及常用的网络前端技术 打算复习&#xff1a; 1、angular√ 2、WEBSOCKET编程√ 1、angular的一些核心概念√ 2、…...

    2024/4/20 16:35:09
  18. 赣州市双眼皮手术还选l华美

    ...

    2024/4/20 16:35:09
  19. 重庆埋线双眼皮价钱7优到星宸

    ...

    2024/4/20 16:35:07
  20. 重庆双眼皮医院排名5需询星宸

    ...

    2024/4/20 16:35:06

最新文章

  1. day-26 H 指数

    思路 利用Arrays.sort()函数排序&#xff0c;然后从后面开始计算H指数 解题方法 H指数初始化为零&#xff0c;排序后从数组最后一个元素开始&#xff0c;如果当前元素大于等于H指数&#xff0c;则比较前一个元素&#xff0c;并将H指数加1&#xff0c;直到循环结束。 Code cl…...

    2024/5/5 4:43:40
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. STM32重要参考资料

    stm32f103c8t6 一、引脚定义图 二、时钟树 三、系统结构图 四、启动配置 &#xff08;有时候不小心短接VCC和GND&#xff0c;芯片会锁住&#xff0c;可以BOOT0拉高试试&#xff08;用跳线帽接&#xff09;&#xff09; 五、最小系统原理图 可用于PCB设计 六、常见折腾人bug…...

    2024/5/1 13:25:10
  4. 外包干了4年,技术退步明显。。。。

    说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入上海某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…...

    2024/5/4 10:53:44
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/4 23:55:17
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/4 18:20:48
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/4 2:59:34
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/4 23:55:01
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57