橙心下沉市场弱网环境下的网络调度方案

591 阅读2分钟

最近部门对小程序进行了一次重大的重构,也对平时的性能瓶颈进行了一次复盘。在我们接近完美的办公环境下(光纤网络,最新的设备),我们的小程序几乎能达到秒开的级别,然而在下沉市场的场景下,用户的使用场景就可能超出我们的想象,经常打开速度达到了10秒以上。在这种场景下,如何优化成为了我们思考的命题。如何在行走在云端的我们和在地上的用户达成一致,变成了我们所需努力的方向。

想象中的速度

现实中

事实上我们将面对信号不好,网速不行的落网环境下,网络资源就会发生拥堵抢跑的现象。如何保证我们的业务代码不被低优先级的请求阻塞,而微信小程序wx.request最大并发数量是10个请求,在这样一个场景下又改如何处理呢

(以下方案是基于项目的方案抽离,项目中并未使用此库)在此设计一个优先级调度中心,以下为具体实现架构

image.png

我们将请求放在一个centerSchedule中进行调度,将任务的优先级,分成lowQueue(低优先)和normalQueue(正常),同时维护一个正在请求的队列fetchingQueue。在请求的过程中先依次清除normalQueue中的队列数据,然后再清理低优先队列中的数据。

npm install easy-schedule -S
class centerSchedule {
    lowPriorityList = [];
    maxWaitingTime;
    threshold = 5;
    _isFetching = false;
    constructor(props) {
        const { lowPriority, maxWaitingTime, threshold, adapter } = props;
        if(lowPriority) {
            this.addLowPriorityList(lowPriority)
        }
        this.maxWaitingTime = maxWaitingTime;
        this.adapter = adapter;
        this.threshold = threshold || 5;
        this.lowQueue = new CommonQueue({maxWaitingTime});
        this.normalQueue = new CommonQueue();
        this.fetchingQueue = new CommonQueue();
    }
}

如图所示,初识化队列的时候,采用装饰器模式,将请求方法放入adapter中。并将响应优先级的参数带入初始化

参数默认
threshold阀值(同时请求数量)5
maxWaitingTime最长等待时间(低优先阻塞过久的时候释放)-
lowPriority低优先匹配规则字符串/正则表达式

举个🌰

import schedule from  'easy-schedule'

function fetch(value) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(value);
            resolve(value)
        }, 1000)
    })
}

const center = new schedule({
    adapter: fetch,
    lowPriority: 'low',
    maxWaitingTime: 200
})


center.request({
    url: 'first'
})
center.request({
    url: 'low',
    
})
center.request({
    url: 'last',
    priority: 'low'
})