SpringBoot 集成RabbitMQ 实现钉钉日报定时发送功能

文章目录

  • [一、RabbitMq 下载安装](#一、RabbitMq 下载安装)
  • 二、开发步骤:
    • [1.MAVEN 配置](#1.MAVEN 配置)
    • [2. RabbitMqConfig 配置](#2. RabbitMqConfig 配置)
    • [3. RabbitMqUtil 工具类](#3. RabbitMqUtil 工具类)
    • [4. DailyDelaySendConsumer 消费者监听](#4. DailyDelaySendConsumer 消费者监听)
    • [5. 测试延迟发送](#5. 测试延迟发送)

一、RabbitMq 下载安装

官网:https://www.rabbitmq.com/docs

二、开发步骤:

1.MAVEN 配置

复制代码
   		<!--RabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.7.7</version>
        </dependency>

2. RabbitMqConfig 配置

复制代码
package com.lq.common.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;


@Configuration
public class RabbitMqConfig {
    /**延迟交换机名称*/
    public static final String  DELAY_EXCHANGE="DelayExchange";
    /**延迟队列名称*/
    public static final String  DELAY_QUEUE="DelayQueue";

    public static final String ROUTING_KEY="delay";


    @Bean
    public CustomExchange customExchange(){
        Map<String, Object> map = new HashMap<>();
        //设置交换机支持延迟消息推送
        map.put("x-delayed-type","direct");
        return new CustomExchange(DELAY_EXCHANGE,"x-delayed-message",true,false,map);
    }

    @Bean
    public Queue delayQueue(){

        return new Queue(DELAY_QUEUE,true);

    }

    @Bean
    public Binding DelayBinding(){
        return BindingBuilder.bind(delayQueue()).to(customExchange()).with(ROUTING_KEY).noargs();
    }

}

3. RabbitMqUtil 工具类

复制代码
package com.lq.common.util;

import com.lq.common.config.RabbitMqConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


@Service
@Slf4j
public class RabbitMqUtil {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    private DateTimeFormatter formatterDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    @PostConstruct
    public void init(){
        /**
         * 消息发送到交换机成功回调函数
         */
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback(){

            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (ack){
                    log.info("消息投递到交换机成功");
                }else {
                    log.error("消息投递到交换机失败,原因->{}",cause);
                }
            }
        });
        /**交换机投递到队列失败回调函数**/
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returned) {
                log.error("投递到队列失败,错误原因->{}",returned);
            }
        });

    }

    /**
     * @Description 发送延迟消息
     * @param content 延迟内容
     * @param delayTime 延迟时间 ,单位ms;  例如 5000 代表 5 秒
     * @Author hqd
     * @Date 2024-10-21
     */
    public Boolean sendDelayMessage(String content,Integer delayTime){
        log.info("消息发送时间->{}",LocalDateTime.now().format(formatterDateTime));

        rabbitTemplate.convertAndSend(RabbitMqConfig.DELAY_EXCHANGE, RabbitMqConfig.ROUTING_KEY, content, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                log.info("延迟时间->{}",delayTime);
                //这个底层就是setHeader("x-delay",i);是一样的 设置延时时间
                message.getMessageProperties().setDelay(delayTime);//单位毫秒
                return message;
            }
        });
        return true;

    }


}

4. DailyDelaySendConsumer 消费者监听

复制代码
package com.lq.daily.mq.consumer;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.lq.common.config.RabbitMqConfig;
import com.lq.daily.dto.DailyDelaySendDTO;
import com.lq.daily.service.ILqDailyService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @Description 日报延迟发送消费者
 * @Author hqd
 * @Date 2024-10-21 16:04
 */
@Slf4j
@Component
public class DailyDelaySendConsumer {
    @Autowired
    private ILqDailyService lqDailyService;

    private DateTimeFormatter formatterDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    @RabbitListener(queues = RabbitMqConfig.DELAY_QUEUE)
    public void dailyDelaySendListener(String content, Channel channel, Message message) throws IOException, InterruptedException{
        log.info("消息接收时间->{}", LocalDateTime.now().format(formatterDateTime));
        log.info("接收消息内容是->{}",content);
        log.info("{}",message.getMessageProperties().getDeliveryTag());
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);

        //处理日报发送业务逻辑
        if (StrUtil.isNotBlank(content)&& content.startsWith("{")){
            DailyDelaySendDTO dto = JSONObject.parseObject(content, DailyDelaySendDTO.class);
            if (ObjectUtil.isNotEmpty(dto)){
                lqDailyService.updateDailyDelaySend(dto.getDailyCode(), LocalDateTime.parse(dto.getDelaySendTime(),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
            }
        }

    }
}

5. 测试延迟发送

复制代码
   @PassToken
    @GetMapping("/testDelayMq")
    @ApiOperation("测试Mq 延迟消息发送")
    public void testDelayMq(){
        DailyDelaySendDTO dto = new DailyDelaySendDTO();
        dto.setDailyCode("DC2024101015135400001");
        dto.setDelaySendTime("2024-10-22 10:58");

        LocalDateTime sendTime = LocalDateTime.parse(dto.getDelaySendTime()+":00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        long between = ChronoUnit.MILLIS.between(LocalDateTime.now(), sendTime);

        rabbitMqUtil.sendDelayMessage(JSON.toJSONString(dto),new Long(between).intValue());
    }
相关推荐
pursue.dreams36 分钟前
Spring Boot整合T-IO实现即时通讯
spring boot·websocket·t-io
-曾牛1 小时前
【LangChain4j快速入门】5分钟用Java玩转GPT-4o-mini,Spring Boot整合实战!| 附源码
java·开发语言·人工智能·spring boot·ai·chatgpt
冬天vs不冷1 小时前
SpringBoot条件注解全解析:核心作用与使用场景详解
java·spring boot·python
考虑考虑1 小时前
Springboot捕获feign抛出的异常
spring boot·后端·spring
〆、风神3 小时前
Spring Boot实战:基于策略模式+代理模式手写幂等性注解组件
spring boot·代理模式·策略模式
Anarkh_Lee3 小时前
解决 Spring Boot 多数据源环境下事务管理器冲突问题(非Neo4j请求标记了 @Transactional 尝试启动Neo4j的事务管理器)
spring boot·后端·spring
日月星辰Ace4 小时前
@TestPropertySource 造成 SpringBoot Test 中对同一个 Bean 使用不同实例
java·spring boot
XuanXu4 小时前
SpringBoot3.0启动流程研究
java·spring boot
bing_1586 小时前
在 Spring Boot 项目中,如何进行高效的数据库 Schema 设计?
数据库·spring boot·后端·数据库schema设计
luckilyil7 小时前
springboot自定义starter(避坑教学)
java·spring boot·spring