SpringBoot RabbitMq 使用

SpringBoot RabbitMq 使用

最近业务场景需要,进行订单支付后,等待指定时间后检查订单是否支付完成,支付失败的话取消订单;支付成功不做其他操作;
通过面向百度开发,决定使用RabbitMq 作为消息中间件实现需要的功能;

通过资料翻阅知道,RabbitMq并没有延迟消息发送这个功能的;但可以通过其的两个特性TTL 和DLX 实现;
TTL :RabbitMq 运行我们为消息获取队列设置有效期; 当消息和队列同时设置时,以小值为准;
DLX:设置在队列上,作用是在于当队列中的消息被拒绝,过期获取队列达到最大长度被排出时,将消息发送到指定的交换器中,通过设置指定好的路由键,到底要接收消息的队列;
(这里个人理解是这样的,若有不当或错误的地方,望指出赐教;)

代码实现

  • 引入依赖,配置RabbitMq
  • 创建交换器和队列,并配置队列属性实现DLX
  • 队列绑定交换器
  • 测试发送TTL消息到设置DLX属性的队列
  • 监听接收到转发消息的队列,实现接收延迟消息

第一步,引入依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

配置RabitMq

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: test
    password: test
    virtual-host: my_test

创建一个配置类,配置创建交换器和队列

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
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;

/**
 * 2019/8/21 14:21
 *
 * @Author lzm
 */
@Configuration
public class DmRabbitMqConfig {


    /**
     * 交换器
     */
    public final static String DM_EXC = "DM_EXC";

    /**
     * 接收DLX转发消息的队列名字,同时作为路由键
     */
    public final static String DM_QUEUE = "DM_QUEUE";

    /**
     * 配置DLX属性的队列名字,同时作为路由键
     */
    public final static String DM_DLX_QUEUE = "DM_DLX_QUEUE";

    /**
     * 创建一个直接模式的交换器
     * @return
     */
    @Bean
    public DirectExchange directExchange(){

        return new DirectExchange(DM_EXC,true,false);
    }

    /**
     * 创建一个普通的队列
     * @return
     */
    @Bean
    public Queue dmQueue(){
        Queue queue = new Queue(DM_QUEUE,true,false,false);
        return queue;
    }

    /**
     * 创建一个队列,并配置DLX 属性,
     * 配置信息可查阅官网:https://www.rabbitmq.com/dlx.html
     * @return
     */
    @Bean
    public  Queue dlxQueue(){
        Map<String,Object> map = new HashMap<>();

        map.put("x-dead-letter-exchange",DM_EXC);
        map.put("x-dead-letter-routing-key",DM_QUEUE);
        Queue queue = new Queue(DM_DLX_QUEUE,true,false,false,map);
        return queue;
    }

    // 两个队列和交换器进行绑定

    @Bean
    public Binding bindingDmQueue(){
        return BindingBuilder.bind(dmQueue()).to(directExchange()).with(DM_QUEUE);
    }

    @Bean
    public Binding bindinDlxQueue(){
        return BindingBuilder.bind(dlxQueue()).to(directExchange()).with(DM_DLX_QUEUE);
    }
}

写个测试类,发送消息进行测试;(进行消息发送时,交换器和队列必须是存在的了,否则会保错;)

@RunWith(SpringRunner.class)
@SpringBootTest
public class DmApplicationTests {

    @Autowired
    private RabbitTemplate template;

    @Test
    public void contextLoads() {
       template.convertAndSend(DmRabbitMqConfig.DM_EXC,DmRabbitMqConfig.DM_DLX_QUEUE, "我是5秒前发生的消息,5秒前是"+LocalDateTime.now(), message -> {
           message.getMessageProperties().setExpiration("5000");
           return message;
       });
    }

写个消息接收类

@Component
public class Test {

    @RabbitListener(queues = DmRabbitMqConfig.DM_QUEUE)
    @RabbitHandler
    public void get(String msg){
        System.out.println("接收到消息,现在时间是:"+ LocalDateTime.now());
        System.out.println(msg);

  }

测试结果

接收到消息,现在时间是:2019-08-21T14:57:22.513
我是5秒前发生的消息,5秒前是2019-08-21T14:57:17.470

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值