一言难尽的HTTP大量请求的坑点

1,933 阅读3分钟

上下文说明

最近在做一款网盘产品,用户可通过操作上传文件夹,或者多选上传多个文件,在项目进行测试时遇到了HTTP请求大量上传文件的bug

请求超时

429

浏览器的坑(浏览器并发请求数量限制)

以下是关于浏览器同域名并发请求的一些说法,这里直接引用:

基于端口数量和线程切换开销的考虑,浏览器不可能无限量的并发请求,因此衍生出来了并发限制和HTTP/1.1的Keep alive。 所以,IE6/7在HTTP/1.1下的并发才2,但HTTP/1.0却是4。 而随着技术的发展,负载均衡和各类NoSQL的大量应用,基本已经足以应对C10K的问题。 但却并不是每个网站都懂得利用domain hash也就是多域名来加速访问。因此,新的浏览器加大了并发数的限制,但却仍控制在8以内

  1. 由于 TCP 协议的限制,PC 端只有65536个端口可用以向外部发出连接,而操作系统对半开连接数也有限制以保护操作系统的 TCP\IP 协议栈资源不被迅速耗尽,因此浏览器不好发出太多的 TCP 连接,而是采取用完了之后再重复利用 TCP 连接或者干脆重新建立 TCP 连接的方法。
  2. 如果采用阻塞的套接字模型来建立连接,同时发出多个连接会导致浏览器不得不多开几个线程,而线程有时候算不得是轻量级资源,毕竟做一次上下文切换开销不小。
  3. 这是浏览器作为一个有良知的客户端在保护服务器。就像以太网的冲突检测机制,客户端在使用公共资源的时候必须要自行决定一个等待期。当超过2个客户端要使用公共资源时,强势的那个邪恶的客户端可能会导致弱势的客户端完全无法访问公共资源。从前迅雷被喷就是因为它不是一个有良知的客户端,它作为 HTTP 协议客户端没有考虑到服务器的压力,作为 BT 客户端没有考虑到自己回馈上传量的义务。

以下是各个浏览器对于同域名并发请求个数的限制,可做参考:

请求个数

因为同域名的请求有一定数量限制,超过限制数目的请求会被阻塞,这也是为什么会前端请求会超时的原因。

服务器的坑

MDN中对http code 429有说明:

在HTTP协议中,响应状态码 429 Too Many Requests 表示在一定的时间内用户发送了太多的请求,即超出了“频次限制”。在响应中,可以提供一个 Retry-After 首部来提示用户需要等待多长时间之后再发送新的请求。

服务端处于安全策略,防止被攻击,因此会限制上传同一个IP单位时间内上传对次数,超过此时请求会直接429被打回去。这也是我们看到当前端请求出现的429失败的原因。

解决方案

目前针对浏览器端的操作是适当放开超时时间、请求分片、请求记录。针对服务端的改造是支持分片上传、提供批量操作的接口。