一种简单实用的平滑迁移流量的算法

之前做项目的时候有个需求,需要把线上流量从主集群迁移到备用集群。由于线上的流量较高,如果直接把流量一下子全切到备用集群的话,会对备有集群有较大压力,同时也会对线上服务的接口性能有较大影响,造成耗时毛刺。

废话不多说,直接看代码

class Solution {
    
    private Client clientA;
    private Client clientB;
    private Client currentClient = clientA;
    /**
     * 开始平滑切换流量的时间戳(默认为0,表示未开始切换)
     */
    private AtomicLong startChangeTimeStamp = new AtomicLong(0);
    /**
     * 平滑切换的时间窗口,即在多长时间内从A集群切换到B集群
     */
    private long changeClientDuration = 60000L;

    public Client warmChangeClient(Client client) {
        // 开始切换新 client
        if (startChangeTimeStamp.get() != 0 && !currentClient.equals(client)) {
            long exceptChangeEndTime = startChangeTimeStamp.get() + changeClientDuration;
            if (System.currentTimeMillis() < exceptChangeEndTime) {
                // 递进步长 (每多少毫秒概率增加1%)
                long step = changeClientDuration / 100;
                long passedTime = System.currentTimeMillis() - startChangeTimeStamp.get();
                long percent = passedTime / step;   // 随时间线性增长的数 [0, 100)
                long random = Math.round(Math.random() * 100);  // [0,100)
                return random < percent ? client : currentClient;
            } else {
                startChangeTimeStamp.set(0);
                lastClient = client;
            }
        }
        return client;
    }
}

总的来说还是基于随机数的算法,目前在线上运行稳定,简单粗暴。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。