短信负载均衡

基本流程

String loadBalancersName = loadBalancers.get(loadBalancerType);
SendLoadBalancer sendLoadBalancer = registerBeanHandler.getBean(loadBalancersName, SendLoadBalancer.class);
String channelLabel = sendLoadBalancer.chooseChannel(smsTemplateVOs,mobiles);;

根据短信模板,选择负载均衡器

根据负载均衡器,选择channel配置文件

根据配置的channel 进行短信发送

负载均衡器

有若干种类

负载均衡器需要实现两个接口

1. 选择channel

2. 获得所有channel

public interface SendLoadBalancer {

    /***
     * @description 根据模板、电话负载均衡发送
     * @param SmsTemplates 模板列表
     * @param mobile 电话号码
     * @return 通道类型
     */
    String chooseChannel(List<SmsTemplateVO> SmsTemplates, Set<String> mobile);

    /***
     * @description 查询拥有当前模板,活跃状态的通道
     * @param SmsTemplates 模板列表
     * @return 通道类型
     */
    Map<String, String> getChannelList(List<SmsTemplateVO> SmsTemplates);
}

channel有两点参数

1. channel        阿里云、腾讯

2. level        权重

@Override
public Map<String, String> getChannelList(List<SmsTemplateVO> SmsTemplates) {
//处理模板
Set<String> channelLabelList = SmsTemplates.stream()
.map(SmsTemplateVO::getChannelLabel).collect(Collectors.toSet());
//查询模板对应的渠道
List<SmsChannelVO> smsChannels =smsChannelService.findChannelInChannelLabel(channelLabelList);
if (!EmptyUtil.isNullOrEmpty(smsChannels)){
return smsChannels.stream()
.collect(Collectors.toMap(SmsChannelVO::getChannelLabel, SmsChannelVO::getLevel));
}
return null;
}

Hash负载均衡

@Component
public class HashSend extends BaseSendLoadBalancer {

    @Override
    public String chooseChannel(List<SmsTemplateVO> SmsTemplates, Set<String> mobile) {
        //获得当前模板对应的渠道
        Map<String, String> channelMap = super.getChannelList(SmsTemplates);
        //取得channel地址List
        Set<String> keySet = channelMap.keySet();
        ArrayList<String> keyList = new ArrayList<String>();
        keyList.addAll(keySet);

        // 使用mobile取余
        int hashCode = mobile.hashCode();
        int serverListSize = keyList.size();
        int serverPos = hashCode % serverListSize;
        return keyList.get(serverPos);
    }

}

1. 根据手机号生成hashcode

2. 对channel长度取余

3. 获得余数

随机

    @Override
    public String chooseChannel(List<SmsTemplateVO> SmsTemplates, Set<String> mobile) {
        //获得当前模板对应的渠道
        Map<String, String> channelMap = super.getChannelList(SmsTemplates);

        // 取得channel地址List
        Set<String> keySet = channelMap.keySet();
        ArrayList<String> keyList = new ArrayList<String>();
        keyList.addAll(keySet);

        Random random = new Random();
        int randomPos = random.nextInt(keyList.size());
        return keyList.get(randomPos);
    }

生成个随机数,然后取余

轮询

    @Override
    public String chooseChannel(List<SmsTemplateVO> SmsTemplates, Set<String> mobile) {
        //获得当前模板对应的渠道
        Map<String, String> channelMap = super.getChannelList(SmsTemplates);

        // 取得通道地址List
        Set<String> keySet = channelMap.keySet();
        ArrayList<String> keyList = new ArrayList<String>();
        keyList.addAll(keySet);

        String channelName = null;
        synchronized (pos) {
            if (pos >= keySet.size())
                pos = 0;
            channelName = keyList.get(pos);
            pos ++;
        }
        return channelName;
    }

对pos上锁,让pos++

如果大于channel大小,让pos重置

根据pos获得channel

加权随机

    @Override
    public String chooseChannel(List<SmsTemplateVO> SmsTemplates, Set<String> mobile) {
        //获得当前模板对应的渠道
        Map<String, String> channelMap = super.getChannelList(SmsTemplates);

        // 取得channel地址List
        Set<String> keySet = channelMap.keySet();
        Iterator<String> iterator = keySet.iterator();

        List<String> serverList = new ArrayList<String>();
        while (iterator.hasNext()) {
            String channel = iterator.next();
            int weight = Integer.valueOf(channelMap.get(channel));
            for (int i = 0; i < weight; i++)
                serverList.add(channel);
        }

        Random random = new Random();
        int randomPos = random.nextInt(serverList.size());

        return serverList.get(randomPos);
    }

channel * 权重,放入serverList

在生成随机数

加权轮询

 @Override
    public String chooseChannel(List<SmsTemplateVO> SmsTemplates, Set<String> mobile) {
        //获得当前模板对应的渠道
        Map<String, String> channelMap = super.getChannelList(SmsTemplates);

        // 取得channel地址List
        Set<String> keySet = channelMap.keySet();
        Iterator<String> iterator = keySet.iterator();

        List<String> channelListHandler = new ArrayList<String>();
        while (iterator.hasNext()) {
            String server = iterator.next();
            Integer weight = Integer.valueOf(channelMap.get(server));
            for (int i = 0; i < weight; i++)
                channelListHandler.add(server);
        }

        String channelName = null;
        synchronized (pos) {
            if (pos > keySet.size())
                pos = 0;
            channelName = channelListHandler.get(pos);
            pos++;
        }
        return channelName;
    }

和加权随机一样

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值