美文网首页
超大规模数据传输速度优化

超大规模数据传输速度优化

作者: 小俊的世界 | 来源:发表于2021-06-22 14:58 被阅读0次

    起因

    最近项目中,有一个统计接口,返回数据大小1.3M,耗时38.89s,而内容下载达到34.57s,这是没有办法接受的。


    image.png image.png

    分析

    并发策略

    利用并发的策略,将原有的接口改成分页查询的接口后
    处理的步骤:
    1.先查询出总数
    2.根据要分多少次查询,设置并发请求
    3.进行并发请求

    class ConcurrentRequests {
      async paging(api, params) { // 通过控制并发数处理
        console.time(`${api.name} time`)
        const back = await api({ ...params, pageSize: 1, currPage: 1 }) // 首次查询到总数
        if (!back.success) throw new Error('接口调用不成功!')
        if (!back.result) throw new Error('没有返回正确的数据结构!')
        if (!params.num) params.num = 4 // 默认为4
        const total = back.result.total
        const totalPage = params.num
        const pageSize = Math.ceil(total / params.num)
    
        const requests = []
        for (let index = 0; index <= totalPage; index++) {
          requests.push(api({ ...params, num: null, pageSize, currPage: index}))
        }
    
        const arr = await Promise.all(requests)
        let list = []
        arr.forEach(item => {
          list = list.concat(item.result.list)
        })
    
        console.timeEnd(`${api.name} time`)
        return list
      }
    }
    
    export const concurrentRequests = new ConcurrentRequests()
    export const pagingConcurrentRequests = concurrentRequests.paging
    

    最终的效果还是相当明显的,13s左右。


    image.png

    多域名并发

    在浏览器的同源策略下,请求并发是有限制的,chrome下的并发数的限制是6个,也就是我一次性超过6个请求的话,其实是不划算的,因为相当于有些请求是需要排队的,那么总时长将会加大。

    基本的思路
    1.为并发请求打上标志,标识为并发请求
    2.拦截并发请求(使用到第三方库ajax-hook),并替换域名后继续请求

    class ConcurrentRequests {
      async paging(api, params) { // 通过控制并发数处理
        console.time(`${api.name} time`)
        const back = await api({ ...params, pageSize: 1, currPage: 1 }) // 首次查询到总数
        if (!back.success) throw new Error('接口调用不成功!')
        if (!back.result) throw new Error('没有返回正确的数据结构!')
        if (!params.num) params.num = 4 // 默认为4
        const total = back.result.total
        const totalPage = params.num
        const pageSize = Math.ceil(total / params.num)
    
        const requests = []
        for (let index = 0; index <= totalPage; index++) {
          // isConcurrentRequest 标识是否并发 用于开启多域名
          requests.push(api({ ...params, num: null, pageSize, currPage: index, isConcurrentRequest: true }))
        }
    
        const arr = await Promise.all(requests)
        let list = []
        arr.forEach(item => {
          list = list.concat(item.result.list)
        })
    
        console.timeEnd(`${api.name} time`)
        return list
      }
    }
    
    export const concurrentRequests = new ConcurrentRequests()
    export const pagingConcurrentRequests = concurrentRequests.paging
    
    
    拦截处理:
     import { proxy } from 'ajax-hook'
     import Vue from 'vue'
    //  请求并发处理
     function dealConcurrentRequest(config) {
       if (config.url && (config.url.indexOf('/promis-web/') !== -1)) {
        if (!config.body) return
        const body = JSON.parse(config.body)
        if (!body.isConcurrentRequest) return
    
        const concurrentDomain = Vue.prototype.$concurrentDomain ? eval(`(${Vue.prototype.$concurrentDomain})`) : []
        const trail = config.url.split('/promis-web/')[1]
        const baseUrl = concurrentDomain[counter++ % concurrentDomain.length]
        config.url = baseUrl + 'promis-web/' + trail
       }
     }
    
     proxy({
      onRequest: (config, handler) => {
        // 请求并发处理
        dealConcurrentRequest(config)
    
        handler.next(config)
      },
      onError: (err, handler) => {
         handler.next(err)
      },
      onResponse: (response, handler) => {
        handler.next(response)
      }
     })
    
    

    我们的备用并发域名设有6个:


    image.png

    设置了并发请求数 20,得出的结果为 5s


    image.png

    相关文章

      网友评论

          本文标题:超大规模数据传输速度优化

          本文链接:https://www.haomeiwen.com/subject/itcyyltx.html