diff --git a/beacon-cache/src/main/java/com/mashibing/cache/controller/CacheController.java b/beacon-cache/src/main/java/com/mashibing/cache/controller/CacheController.java index 78b73c8..895368b 100644 --- a/beacon-cache/src/main/java/com/mashibing/cache/controller/CacheController.java +++ b/beacon-cache/src/main/java/com/mashibing/cache/controller/CacheController.java @@ -98,7 +98,7 @@ public class CacheController { return result; } - @PostMapping("smember/{key}") + @GetMapping("smember/{key}") public Set smember(@PathVariable(value = "key") String key) { log.info("【缓存模块】smember: key = {},", key); Set value = redisClient.sMembers(key); diff --git a/beacon-common/src/main/java/com/mashibing/common/clients/BeaconCacheClient.java b/beacon-common/src/main/java/com/mashibing/common/clients/BeaconCacheClient.java index 7cefac9..b9fac91 100644 --- a/beacon-common/src/main/java/com/mashibing/common/clients/BeaconCacheClient.java +++ b/beacon-common/src/main/java/com/mashibing/common/clients/BeaconCacheClient.java @@ -52,7 +52,7 @@ public interface BeaconCacheClient { @PostMapping("cache/sinterstr/{key}/{sinterkey}") Set sinterStr(@PathVariable String key, @PathVariable String sinterkey, @RequestBody String... value); - @PostMapping("cache/smember/{key}") + @GetMapping("cache/smember/{key}") Set smember(@PathVariable String key); @PostMapping("cache/zadd/{key}/{member}/{score}") diff --git a/beacon-common/src/main/java/com/mashibing/common/constant/CacheConstant.java b/beacon-common/src/main/java/com/mashibing/common/constant/CacheConstant.java index 5ad1855..11fc45c 100644 --- a/beacon-common/src/main/java/com/mashibing/common/constant/CacheConstant.java +++ b/beacon-common/src/main/java/com/mashibing/common/constant/CacheConstant.java @@ -55,4 +55,10 @@ public class CacheConstant { @Description("小时限流规则前缀") public static final String LIMIT_HOUR = "limit_hour:"; + + @Description("通道channel前缀") + public static final String CHANNEL = "channel:"; + + @Description("客户和通道绑定信息前缀") + public static final String CLIENT_CHANNEL = "client_channel:"; } diff --git a/beacon-common/src/main/java/com/mashibing/common/constant/RabbitMQConstant.java b/beacon-common/src/main/java/com/mashibing/common/constant/RabbitMQConstant.java index 374c1c3..9215f58 100644 --- a/beacon-common/src/main/java/com/mashibing/common/constant/RabbitMQConstant.java +++ b/beacon-common/src/main/java/com/mashibing/common/constant/RabbitMQConstant.java @@ -27,4 +27,9 @@ public interface RabbitMQConstant { * 推送短信状态报告队列 */ String SMS_PUSH_REPORT = "sms_push_report_topic"; + + /** + * + */ + String SMS_GATEWAY = "sms_gateway_topic_"; } diff --git a/beacon-common/src/main/java/com/mashibing/common/enums/ExceptionEnums.java b/beacon-common/src/main/java/com/mashibing/common/enums/ExceptionEnums.java index c63d2df..699273a 100644 --- a/beacon-common/src/main/java/com/mashibing/common/enums/ExceptionEnums.java +++ b/beacon-common/src/main/java/com/mashibing/common/enums/ExceptionEnums.java @@ -11,6 +11,7 @@ import lombok.Getter; @Getter public enum ExceptionEnums { + UNKNOWN_ERROR(-999, "未知的错误!!!"), ERROR_APIKEY(-1, "非法的apikey"), IP_NOT_WHITE(-2, "请求的ip不在白名单内"), ERROR_SIGN(-3, "无可用签名"), @@ -25,6 +26,8 @@ public enum ExceptionEnums { BLACK_CLIENT(-15, "手机号是客户黑名单!!"), LIMIT_MINUTE(-16, "达到分钟限流阈值!!"), LIMIT_HOUR(-17, "达到小时限流阈值!!"), + NO_CHANNEL(-18, "没有可用通道!!!"), + ; private final int code; diff --git a/beacon-strategy/src/main/java/com/mashibing/strategy/service/strategyfilter/impl/RouteStrategyFilter.java b/beacon-strategy/src/main/java/com/mashibing/strategy/service/strategyfilter/impl/RouteStrategyFilter.java index aef08af..bdfcb19 100644 --- a/beacon-strategy/src/main/java/com/mashibing/strategy/service/strategyfilter/impl/RouteStrategyFilter.java +++ b/beacon-strategy/src/main/java/com/mashibing/strategy/service/strategyfilter/impl/RouteStrategyFilter.java @@ -1,10 +1,27 @@ package com.mashibing.strategy.service.strategyfilter.impl; +import com.mashibing.common.constant.CacheConstant; +import com.mashibing.common.constant.RabbitMQConstant; +import com.mashibing.common.enums.ExceptionEnums; +import com.mashibing.common.exception.StrategyException; import com.mashibing.common.pojo.StandardSubmit; +import com.mashibing.strategy.feignclient.CacheClient; import com.mashibing.strategy.service.strategyfilter.StrategyFilter; +import com.mashibing.strategy.utils.ChannelTransferUtil; +import com.mashibing.strategy.utils.StrategyCheckFailedUtil; import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.AmqpException; +import org.springframework.amqp.core.AmqpAdmin; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Comparator; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + /** * @author heqijun * @ClassName: RouteStrategyFilter @@ -16,8 +33,99 @@ import org.springframework.stereotype.Service; @Service(value = "route") public class RouteStrategyFilter implements StrategyFilter { + @Autowired + CacheClient cacheClient; + + @Autowired + StrategyCheckFailedUtil strategyCheckFailedUtil; + + @Autowired + private AmqpAdmin amqpAdmin; + + @Autowired + private RabbitTemplate rabbitTemplate; + + private static final String STRATEGY_NAME = "路由"; @Override public void strategy(StandardSubmit submit) { - log.info("【策略模块-路由校验】。。。"); + log.info("【策略模块-路由策略】开始===================================="); + //1、拿到客户id + Long clientId = submit.getClientId(); + + //2、基于redis获取当前客户绑定的所有通道信息 + Set clientChannels = cacheClient.smember(CacheConstant.CLIENT_CHANNEL + clientId); + + //3、将获取到的客户通道信息根据权重做好排序 + TreeSet clientWeightChannels = new TreeSet<>(new Comparator() { + @Override + public int compare(Map o1, Map o2) { + int o1Weight = Integer.parseInt(o1.get("clientChannelWeight") + ""); + int o2Weight = Integer.parseInt(o2.get("clientChannelWeight") + ""); + return o2Weight - o1Weight; + } + }); + clientWeightChannels.addAll(clientChannels); + + boolean ok = false; + Map channel = null; + Map clientChannel = null; + //4、基于排好序的通道选择,权重更高的 + for (Map clientWeightChannel : clientWeightChannels) { + //5、如果客户和通道的绑定关系可用,直接去基于Redis查询具体的通道信息 + if ((int) (clientWeightChannel.get("isAvailable")) != 0) { + // 当前关系不可用,直接进行下次循环,选择权重相对更低一点的 + continue; + } + + //6、如果通道信息查询后,判断通道睡否可用,其次运营商可以匹配。 + channel = cacheClient.hget(CacheConstant.CHANNEL + clientWeightChannel.get("channelId")); + if ((int) (channel.get("isAvailable")) != 0) { + // 当前通道不可用,选择权重更低的通道~ + continue; + } + // 获取通道的通讯方式 + Integer channelType = (Integer) channel.get("channelType"); + if (channelType != 0 && submit.getOperatorId() != channelType) { + // 通道不是全网通,并且和当前手机号运营商不匹配 + continue; + } + + //7、如果后期涉及到的通道的转换,这里留一个口子 + Map transferChannel = ChannelTransferUtil.transfer(submit, channel); + + // 找到可以使用的通道了 + ok = true; + clientChannel = clientWeightChannel; + break; + } + + if (!ok) { + log.info("【策略模块-路由策略】没有选择到可用的通道!!"); + submit.setErrorMsg(ExceptionEnums.NO_CHANNEL.getMsg()); + strategyCheckFailedUtil.smsSendLog(submit, STRATEGY_NAME); + strategyCheckFailedUtil.smsPushReport(submit, STRATEGY_NAME); + throw new StrategyException(ExceptionEnums.NO_CHANNEL); + } + + //8、基于选择的通道封装submit的信息 + submit.setChannelId(Long.parseLong(channel.get("id") + "")); + submit.setSrcNumber("" + channel.get("channelNumber") + clientChannel.get("clientChannelNumber")); + + try { + //9、声明好队列名称,并构建队列 + String queueName = RabbitMQConstant.SMS_GATEWAY + submit.getChannelId(); + amqpAdmin.declareQueue(QueueBuilder.durable(queueName).build()); + + //10、发送消息到声明好的队列中 + rabbitTemplate.convertAndSend(queueName, submit); + } catch (AmqpException e) { + log.error("【策略模块-路由策略】声明通道对应队列以及发送消息时出现了问题!"); + submit.setErrorMsg(e.getMessage()); + strategyCheckFailedUtil.smsSendLog(submit, STRATEGY_NAME); + strategyCheckFailedUtil.smsPushReport(submit, STRATEGY_NAME); + throw new StrategyException(ExceptionEnums.UNKNOWN_ERROR.getCode(), e.getMessage()); + } + log.info("【策略模块-路由策略】路由完毕!!!"); + } } diff --git a/beacon-strategy/src/main/java/com/mashibing/strategy/utils/ChannelTransferUtil.java b/beacon-strategy/src/main/java/com/mashibing/strategy/utils/ChannelTransferUtil.java new file mode 100644 index 0000000..ac13823 --- /dev/null +++ b/beacon-strategy/src/main/java/com/mashibing/strategy/utils/ChannelTransferUtil.java @@ -0,0 +1,27 @@ +package com.mashibing.strategy.utils; + +import com.mashibing.common.pojo.StandardSubmit; + +import java.util.Map; + +/** + * @author heqijun + * @ClassName: ChannelTransferUtil + * @Description: 通道转换工具类,暂时无用 + * @date 2025/6/11 19:34 + */ + +public class ChannelTransferUtil { + + /** + * 暂时什么都不做 + * + * @param submit submit + * @param channel 原通道 + * @return 新通道 + */ + public static Map transfer(StandardSubmit submit, Map channel) { + return channel; + } + +} diff --git a/beacon-strategy/src/main/java/com/mashibing/strategy/utils/DirtyWordTree.java b/beacon-strategy/src/main/java/com/mashibing/strategy/utils/DirtyWordTree.java index 4f089dc..f44e9df 100644 --- a/beacon-strategy/src/main/java/com/mashibing/strategy/utils/DirtyWordTree.java +++ b/beacon-strategy/src/main/java/com/mashibing/strategy/utils/DirtyWordTree.java @@ -73,7 +73,6 @@ public class DirtyWordTree { */ public static Set getDirtyWord(String text) { - //拿到敏感词树 Map currentMap; Set result = new HashSet<>();