摘要:服务端代码网页端代码函数传入请求的为了获取请求数据,将改为。捕获三个请求的时间,分别为,,。对于连续的相同请求,会阻塞后面的请求,直到前面的完成。这也是为什么打开谷歌开发者控制台,请求没有等待,立即执行了。
最近在研究慢请求监控的问题,写了一个简单的测试代码:在网页端(index.html)通过fetch函数向服务端获取数据,然后打印请求耗时。
</>复制代码
function requestData() {
let start = new Date();
fetch("http://localhost:3000/company/basic")
.then(res => {
return res.json();
})
.then(res => {
let span = new Date() - start;
console.log("span:", span);
});
}
requestData();
在服务端通过setTimeout延时1500s才返回数据(服务端使用ExpressJS)。
</>复制代码
app.get("/company/basic", (req, res) => {
setTimeout(function() {
res.send({ hello: "Hello Fundebug!" });
}, 1500);
});
不出所料,span数据都略微大于 1500。
而后,我突发奇想,假设我同时发送多个请求会怎么样呢?于是有了如下代码:
</>复制代码
[1, 2, 3].forEach(function() {
requestData();
});
结果好像也没问题,在 Chrome 浏览器下面是这个效果:
接入 Fundebug 慢请求监控测试于是愉快地接入 Fundebug 监控:
</>复制代码
并设置如果请求时长超过 2 秒就上报:
</>复制代码
if ("fundebug" in window) {
fundebug.httpTimeout = 2000;
}
本以为刷新页面,应该不会收到报错。
结果,万万没想到的是,Fundebug 收到 2 个慢请求报错。
这不科学啊!
点开错误详情,可以看到具体的报错信息。一个请求耗时 3018 毫秒,一个请求耗时 4525 毫秒。
也就是说,第一个请求没问题,假设是 1500 毫秒。我们把三个请求的时间放一起看看有何规律:1500,3018,4524。他们近似成等差数列,相差 1500 毫秒。于是,我怀疑三个请求是一个一个阻塞式的,而不是并发的。
测试并发请求不同 API 的情况为了验证这一点,我将测试改为请求三个不同的 API 接口。
服务端代码:
</>复制代码
app.get("/company/basic", resp);
app.get("/company/basic1", resp);
app.get("/company/basic2", resp);
function resp(req, res) {
setTimeout(function() {
res.send({ hello: "Hello Fundebug!" });
}, 1500);
}
网页端代码(requestData函数传入请求的 URL):
</>复制代码
[
"http://localhost:3000/company/basic",
"http://localhost:3000/company/basic1",
"http://localhost:3000/company/basic2"
].forEach(function(item) {
requestData(item);
});
为了获取请求数据,将httpTimeout改为 1500。
</>复制代码
if ("fundebug" in window) {
fundebug.httpTimeout = 1500;
}
Fundebug 捕获三个请求的时间,分别为 1526,1525,1529。
至此大体验证了刚刚的假设:对同一个 API 接口的并发请求会被阻塞,对不同的 API 接口并发请求正常执行。
那么为什么会被阻塞呢?意图何在?接下来慢慢给各位介绍。
背后的原因在StackOverflow上找到了答案:
</>复制代码
Yes, this behavior is due to Chrome locking the cache and waiting to see the result of one request before requesting the same resource again. The answer is to find a way to make the requests unique.
也就是说,Chrome 特意做了这样的设计。对于连续的相同请求,Chrome 会阻塞后面的请求,直到前面的完成。通过判断前面的请求返回的 Header 里面的缓存设置来决定下一步的行动。
我们可以做个实验来验证一下。
缓存实验
服务端设置缓存 2 秒
在服务端的接口返回代码中配置缓存时间
</>复制代码
res.setHeader("Cache-Control", "public, max-age=2");
服务端设置不缓存
</>复制代码
res.setHeader(
"Cache-Control",
"private, no-cache, no-store, must-revalidate"
);
Chrome 开发者面板设置Disable Cache
最后的疑问为什么打开和不打开谷歌开发者控制台,行为会不一样了?
其实是有原因的,而且这个干扰项一度成功阻止了我发现问题的本质。当我们在开发前端项目的时候,代码的改动希望能够实时地反应到网页上,而不是受到浏览器缓存的影响,但是我们发现往往刷新页面的时候没有真的去服务端获取数据,还是老的信息。于是,我们会去配置一个选项,将Disable Cache设置为true。也就是说,在开发环境下,缓存是被禁用了的,也就不存在等待第一个请求返回然后判断其 Header 里面Cache-Control设置的问题。这也是为什么打开谷歌开发者控制台,请求没有等待,立即执行了。
关于FundebugFundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家免费试用!
版权声明转载时请注明作者 Fundebug以及本文地址:
https://blog.fundebug.com/2019/07/17/chrome-stall-multiple-same-request/
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/105701.html
摘要:前端是应用服务器处理之前的部分,前端主要包括等各种资源,针对不同的资源有不同的优化方式。常见方法合并多个文件和文件,利用整合图像,使用在实际的页面嵌入图像数据,合理设置缓存等。 web前端是应用服务器处理之前的部分,前端主要包括:HTML,CSS,javascript,image等各种资源,针对不同的资源有不同的优化方式。 内容优化 (1)减少HTTP请求数:这条策略是最重要最有效...
摘要:高性能代码的最佳实践前言在这篇文章中,我们将讨论几个有助于提升应用程序性能的方法。要获得有关应用程序需求的最好最可靠的方法是对应用程序执行实际的负载测试,并在运行时跟踪性能指标。 showImg(https://segmentfault.com/img/bVbtgk4?w=256&h=254); 高性能Java代码的最佳实践前言 在这篇文章中,我们将讨论几个有助于提升Java应用程序性...
摘要:提高用户访问网站的响应速度与网站的可用性,解决网络带宽小用户访问量大网点分布不均等问题。网站加速什么是加速网站加速相信大家都知道,当一个用户打开一个新网站的时候,如果网站打开的速度很慢的话,用户是很难继续浏览的;因此,很多网站运营人会想方设法的去提升网站的加载速度。例如用CDN加速,能帮助一个网站能够快速打开的有效和实用方法。 我们相信速度是一个成功网站的必备要素之一,速度不够快,会降...
摘要:摘要阿里云主要分为离线分析和在线分析两种功能。演讲嘉宾简介勋臣,阿里云内核团队技术专家,目前阿里云专家系统开发。通过诊断报告定位性能下降原因。 摘要:阿里云CloudDBA主要分为离线分析和在线分析两种功能。帮助用户节省成本,定位问题,分析原因并推荐解决方法。CloudDBA可以做到实时诊断,离线诊断和SQL优化。并且通过MySQL的参数调优,检测参数的不合理或者准备的延迟的情况。 演...
阅读 2099·2021-08-21 14:09
阅读 560·2019-08-30 15:44
阅读 2187·2019-08-29 16:32
阅读 1453·2019-08-29 15:36
阅读 3578·2019-08-29 12:43
阅读 2845·2019-08-29 11:14
阅读 499·2019-08-28 18:26
阅读 2312·2019-08-26 13:57
极致性价比!云服务器续费无忧!
Tesla A100/A800、Tesla V100S等多种GPU云主机特惠2折起,不限台数,续费同价。
NVIDIA RTX 40系,高性价比推理显卡,满足AI应用场景需要。
乌兰察布+上海青浦,满足东推西训AI场景需要