Chrome访问.NET MVC微服务时为何未启用多线程?
踩过同款坑!Chrome下.NET MVC接口并发访问异常的原因与解决
问题还原
我先理理你遇到的情况:
- 本地搭了个.NET MVC微服务,写了个简单的接口,代码是这样的:
public class HomeController : Controller { [HttpGet("Hello")] [HttpPost("Hello")] public IActionResult Hello(int a, int b, int c) { Thread.Sleep(5000); // 故意等5秒模拟耗时操作 return View(); } }
- 测试时同时发起两次对
/Hello的访问,结果Chrome里两次请求居然是串行执行的——得等第一个请求5秒返回后,第二个才开始跑;换IE就正常,两个请求并行执行,同时等5秒后返回。
为啥Chrome会搞这出?
这真不是你服务端的问题!是Chrome的同一域名下同URL GET请求的排队优化在作祟:
- Chrome为了减少重复请求、优化缓存,对于同一会话(比如同一个浏览器窗口)里的完全相同的GET请求,会自动把它们排成一队,前一个请求处理完了才发下一个,不会同时发出去
- 你刚好是用GET请求访问同一个
/Hello接口,触发了这个机制,看起来就像服务端没处理并发,但其实是浏览器把请求按住了 - IE没有这个默认的排队策略,所以直接并行发请求,你看到的才是服务端真实的并发表现
怎么验证&解决?
快速验证方法
- 换成POST请求测试:Chrome对POST请求不会做这种排队,你会看到两个请求并行执行
- 给GET请求加不同的参数:比如第一次用
/Hello?a=1&b=2&c=3,第二次用/Hello?a=1&b=2&c=4,让URL变得不一样,Chrome就会并行发送了
代码/前端层面的解决办法
如果业务上确实需要同一URL的GET请求能被Chrome并行处理,有两种思路:
- 在接口里加禁用缓存的响应头,告诉Chrome别缓存这个请求,也别排队:
[HttpGet("Hello")] public IActionResult Hello(int a, int b, int c) { // 添加禁用缓存的响应头 Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate"; Response.Headers["Pragma"] = "no-cache"; Response.Headers["Expires"] = "0"; Thread.Sleep(5000); return View(); }
- 前端发起请求时,给每个GET请求加个随机参数(比如时间戳
?t={new Date().getTime()}),确保每次请求的URL都是唯一的,Chrome就不会排队了
最后说一句
这种跨浏览器的差异真的很容易误导人,我当初也以为是自己的微服务并发配置有问题,折腾了好半天。以后遇到这种情况,先抓个包看看浏览器到底有没有同时发请求,就能快速定位问题啦~
内容的提问来源于stack exchange,提问作者WL_Law
相关产品推荐
相关产品推荐

