定时器/ mq /监听器

文章描述了一个Java类,用于定期扫描Redis中的点赞数据(ZSet集合),计算点赞总数并将其通过MQ发送给业务层进行进一步处理。同时涉及到了SpringBoot的定时任务(@Scheduled)和XxlJob插件,以及数据库操作和消息队列的集成。
摘要由CSDN通过智能技术生成

添加注解 调用定时器: 

@EnableScheduling
@Component
@Slf4j
@RequiredArgsConstructor
public class LikedTimesCheckTask {
    /* 定时任务扫描 redis 点赞总数zset 集合 ,获取点赞数 发送MQ 消息*/

    /*业务类型的集合:QA(问答) "NoTe 笔记"*/

    private  final  myTimecountsconfig myTimecountsconfig;
            // 两个类型 定义两个常量:::::
    private static final int MAX_BIZ_SIZE = 30; // 每次去取多少:::

    private final ILikedRecordService recordService; // 注入业务层

    @Scheduled(fixedDelay = 20000) // 20000 毫秒co  fix 20000 固定时间 时间
    public void checkLikedTimes(){
        for (String bizType : myTimecountsconfig.getBIZ_TYPES()) {
            recordService.readLikedTimesAndSendMessage(bizType, MAX_BIZ_SIZE); // 根据业务类型 然后去取多少数据:
        }
    }

}

业务层注入  创建业务

 

    @XxlJob("issueCoupon")  / @XxlJob 注解可以直接把优惠卷发放

  @XxlJob("issueCoupon")  /
      public  void  PromotionTask(){
//1、查询需要发放的优惠券数据:
// select * from 优惠券表 where status = 未开始 and 发放开始时间[issueBeginTime] <= 当前时间
// 如果没有查询出数据,则直接返回

          List<Coupon> list = couponService.lambdaQuery()
                  .eq(Coupon::getStatus, CouponStatus.UN_ISSUE)
                  .lt(Coupon::getIssueBeginTime, LocalDateTime.now()).list();
          if (CollUtils.isEmpty(list)){
              return;
          }

          //TODO 优惠券
//2、循环遍历优惠券,更新优惠券的状态为发放中 CouponStatus.ISSUING 把2变3

          for (Coupon coupon : list) {
              couponService.lambdaUpdate()
                      .set(Coupon::getStatus,CouponStatus.ISSUING.getValue())
                      .eq(Coupon::getId,coupon.getId())
                      .update();

//   还要判断是否需要生成兑换码,如果需要则使用SpringAsync异步操作生成验证码
//   判断条件: 优惠券类型必须是兑换码,且优惠券状态必须是待发放

              if(coupon.getObtainWay()== ObtainType.ISSUE && coupon.getStatus()==CouponStatus.DRAFT){
                  coupon.setIssueEndTime(coupon.getTermEndTime());
                  exchangeCodeService.generateExchangeCode(coupon);
              }

 

 

 

 业务代码编写 好 mq 打包发送 

使用mq需要1. 导入依赖 2. 配置
      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

 

   /*根据业务类型批量从redis 的 zset 集合中读取不同业务的点赞数量 发送mq 消息 并且持久化到数据库 查询的时候再继续加载*/
    @Override
    public void readLikedTimesAndSendMessage(String bizType, int maxBizSize) {
        // 先移除点赞总数 数据转换  发送消息:

        // 1.读取并移除Redis中缓存的点赞总数  String LIKE_BIZ_KEY_PREFIX = "likes:set:biz:{}"
       // popMin  取出zset 集合中分数最少的前30个 点赞数最少的前多少个 ::: 这个命令
        String zsetkey = StringUtils.format(RedisConstants.LIKE_BIZ_KEY_PREFIX,bizType);
        // ps 如果是空的直接返回: 从zset集合中去取出分数最少的:
        Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().popMin(zsetkey,maxBizSize);  // key 去取的数量 30 个 从定时任务器中已经弄出来了
        if (CollUtils.isEmpty(set)) {
            return;
        }
        // 2.数据转换  读取是上面的set  Set<ZSetOperations.TypedTuple<String>> set 里面的数据包含两个: 业务 Id score分数 点赞数
        ArrayList<LikedTimesDTO> dtoList = new ArrayList<>();
        for (ZSetOperations.TypedTuple<String> tuple : set) {
            Double score = tuple.getScore(); //点赞次数
            Long bizId = Long.valueOf(tuple.getValue()); // 业务
            if (ObjectUtils.isEmpty(bizId) || ObjectUtils.isNull(score)) {
                continue;
            }
            LikedTimesDTO dto = new LikedTimesDTO(Long.valueOf(bizId), score.intValue());
            dtoList.add(dto);


        }
        // 3.批量修改点赞数量 发送mq 一个一个发比较好: 这边打包发送:
        if (CollUtils.isNotEmpty(dtoList)){  // 如果不为空
            log.info("需要更新点赞数的业务有" ,dtoList);
            mqHelper.send(MqConstants.Exchange.LEARNING_EXCHANGE, // 交换机
                    StringUtils.format(MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE,bizType), // 路由key
                    dtoList // 内容
                    );
        }

编写一个监听器 监听到打包发来的dtolist数据然后更改数据库

@Component
@RequiredArgsConstructor
@Slf4j
public class LikeTImesChangeListener {

private  final IInteractionReplyService replyService;
    @RabbitListener(
            bindings = {
                    @QueueBinding(
                            value = @Queue(MqConstants.Queue.QA_LIKED_TIMES_QUERE),
                            exchange = @Exchange(name = MqConstants.Exchange.LEARNING_EXCHANGE),
                            key = {MqConstants.Key.QA_LIKED_TIMES_KEY}
                    )
            }
    )
    public void  likedTimesChange(List<LikedTimesDTO> dtoList){
        log.info("监听到消息并且点赞数变更");
        for (LikedTimesDTO dto : dtoList) {
            replyService.lambdaUpdate()
                    .set(InteractionReply::getLikedTimes,dto.getLikedTimes())
                    .eq(InteractionReply::getId,dto.getBizId())
                    .update();
        }

    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值