按权重随机调用算法

思路是:给每个来源系统设置每天的最大调用量、调用阈值等信息,该来源系统调用不同的第三方接口,给每个第三方接口设置权重,以实现按权重随机调用第三方接口的效果

代码实现

配置表 POJO

public class TwoElementConfig {
    
    
    @Id
    private Long id;
    /**来源系统*/
    private String source;
    /**第三方接口*/
    private String targetSource;
    /**是否开启(1启用,0禁用,默认禁用)*/
    private Integer open;
    /**调用次数上限*/
    private Integer callLimit;
    /**预警阈值,总值100(达到上限的x%进行提醒)*/
    private Integer warnThreshold;
    /**权重*/
    private Integer weight;
    /**调用系统负责人姓名*/
    private String name;
    /**调用系统负责人手机号*/
    private String mobile;
    /**创建时间*/
    private Date createTime;
    /**更新时间*/
    private Date updateTime;

}

核心算法接口

  • 方式一
// 配置信息列表
List<TwoElementConfig> configs=twoElementConfigService.listTwoElementConfig(vo);

// 2、获取权重
Integer weightSum = 0;
String targetSource = "";
for (TwoElementConfig co : configs) {
    
    
    weightSum += co.getWeight();
}
if (weightSum <= 0) {
    
    
    throw new IllegalArgumentException("权重信息不能小于等于0");
}
// n in [0, weightSum)
Integer n = new Random().nextInt(weightSum);
Integer m = 0;
for (TwoElementConfig co : configs) {
    
    
    if (m <= n && n < m + co.getWeight()) {
    
    
        targetSource = co.getTargetSource();
        break;
    }
    m += co.getWeight();
}

// 调用第三方接口
if (Objects.equals(targetSource, "AA")) {
    
    
    result = nanJingYiShuService.verifyAA(cerName, cerNo);
}
if (Objects.equals(targetSource, "BB")) {
    
    
    result = juFengService.verifyByBB(cerName, cerNo);
}

  • 方式二
package cn.yto.ias.base.util;

import cn.yto.ias.common.entity.TwoElementConfig;
import org.apache.commons.lang3.StringUtils;

import java.util.Random;
import java.util.TreeMap;

/**
 * @Author yanyg
 * @Date 2020/6/23 14:01
 * @Descripetion admin
 */
public class WeightUtil {
    
    

    /**
     * @param config
     * @return 二要素接口名称
     */
    public static String getTargetSource(TwoElementConfig config) {
    
    
        // 获取权重
        Integer weightSum = 0;
        String[] twoElementArr = config.getWeight().split(",");

        //以权重区间段的后面的值作为key存当前信息
        TreeMap<Integer, String> map = new TreeMap<>();
        for (String element : twoElementArr) {
    
    
            String eleName = element.split(":")[0];
            String weight = element.split(":")[1];
            weightSum += Integer.valueOf(weight);
            map.put(weightSum, eleName);
        }
        if (weightSum <= 0) {
    
    
            throw new IllegalArgumentException("权重信息不能小于等于0");
        }

        // random in [1, weightSum]
        Integer random = new Random().nextInt(weightSum) + 1;
        // ceilingKey(K key) 方法用于返回map中最小键大于或等于给定的入参random,如果不存在这样的最小键,返回null
        return map.get(map.ceilingKey(random));
    }


    public static void main(String[] args) {
    
    
        String weight = "JuFeng:30,NanJingYiShu:90,AA:60";
        TwoElementConfig config = new TwoElementConfig();
        config.setWeight(weight);
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;

        for (int i = 1; i <= 180; i++) {
    
    
            String targetSource = getTargetSource(config);
            switch (targetSource) {
    
    
                case "JuFeng":
                    count1++;
                    break;
                case "NanJingYiShu":
                    count2++;
                    break;
                case "AA":
                    count3++;
                    break;
                default:
                    break;
            }
        }
        System.out.println("JuFeng 出现次数:" + count1);
        System.out.println("NanJingYiShu 出现次数:" + count2);
        System.out.println("AA 出现次数:" + count3);
        System.out.println("总次数:" + (count1 + count2 + count3));

    }
}

参考文档

猜你喜欢

转载自blog.csdn.net/thebigdipperbdx/article/details/106837930