RabbitMQ用法



  • 前言
  • 一、rabbitmq配置
  • 二、队列交换机配置
  • 1.RabbitmqConfig类配置队列,路由,交换机
  • 2.生产消息
  • 3.消费消息
  • 4.消息确认和丢弃
  • 4.工具测试
  • 总结




前言

提示:上一篇说完了rabbitmq基本知识,这篇文章主要是通过Topic类型来生产和消费消息


一、rabbitmq配置

1. application.properties配置文件

# rabbitmq
# 配置虚拟机
spring.rabbitmq.virtual-host=/
# 开启消息确认机制 confirm 异步
spring.rabbitmq.publisher-confirm-type=correlated
# 开启return机制
spring.rabbitmq.publisher-returns=true
# 消息开启手动确认
spring.rabbitmq.listener.simple.acknowledge-mode=manual
spring.rabbitmq.host=192.168.100.49
spring.rabbitmq.port=5672
spring.rabbitmq.username=open_sa
spring.rabbitmq.password=open_sa

2. pom依赖

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

二、队列交换机配置

1.RabbitmqConfig类配置队列,路由,交换机

代码如下(示例):

/**
   * @param
   * @return
   * @Description 绑定队列
   * @author lihongqiang
   * @date 2021-6-4 17:00
   */
  @Bean
  public Queue queueTopicStructuredProjectData() {
    return new Queue("que.data");
  }
    /**
   * @param
   * @return
   * @Description 绑定key
   * @author lihongqiang
   * @date 2021-6-4 17:01
   */
  @Bean
  public TopicExchange exchangeTopicStructuredProjectData() {
    return new TopicExchange("topic.date");
  }
    /**
   * @param
   * @return
   * @Description 绑定 exchange and queue *(星号):可以(只能)匹配一个单词 #(井号):可以匹配多个单词(或者零个)
   * @author lihongqiang
   * @date 2021-6-4 16:57
   */
  @Bean
  public Binding bindingTopic() {
    return BindingBuilder.bind(queueTopicStructuredProjectData()).to(exchangeTopicStructuredProjectData()).with("que.data");
  }

注意:绑定队列规则时#和*用法为:with(“que.#”)类似

2.生产消息

生产者生产消息发送至队列中:

@Resource
    private RabbitTemplate rabbitTemplate;
    @Override
    public void sendWork(String str) {

       rabbitTemplate.convertAndSend("que.data", str );
    }
	public void sendTopic() {

        String str = "消费者1接收到:测试topic类型";

        rabbitTemplate.convertSendAndReceive("e-exchange", "que.data", str);

    }

这两种方法都可以发送消息,此处可以自己用postman调用模拟发送消息。convertSendAndReceive第一个参数为交换机

3.消费消息

消费者监听队列获取消息:

@RabbitListener(queues = "que.data")
    public void receiveMsg1(Message message, Channel channel) throws IOException {
        log.info("消费者1接收到:{}" , new String(message.getBody()));
    }

4.消息确认和丢弃

消息确认有手动和自动两种方式:

  1. 自动确认
  2. 手动确认
    配置文件中开启手动确认方式
spring.rabbitmq.listener.simple.acknowledge-mode=manual
  1. 确认消息

ack表示确认消息。multiple:false只确认该delivery_tag的消息,true确认该delivery_tag的所有消息

channel.basicAck(msg.getMessageProperties().getDeliveryTag(),false);
  1. 拒绝消息

Reject表示拒绝消息。requeue:false表示被拒绝的消息是丢弃;true表示重回队列

channel.basicReject(msg.getMessageProperties().getDeliveryTag(),false);
  1. 拒绝消息

nack表示拒绝消息。multiple表示拒绝指定了delivery_tag的所有未确认的消息,false表示不是重回队列

channel.basicNack(msg.getMessageProperties().getDeliveryTag(),false,false);
  1. 上面消费者接收到消息后,可以按下列方式处理
log.info("消费者1接收到:{}" , new String(message.getBody()));
        try{
            String str = new String(message.getBody());
            if(true){
                //数据正确处理后
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }else {
               //数据处理失败需要丢弃或重回队列时 
                //方式二选一,具体要看业务逻辑
                //拒绝消息,false消息丢弃
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
                //拒绝消息,拒绝指定了delivery_tag的所有未确认的消息,false不回队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
            }
        }catch (Exception e){
            //方式二选一,具体要看业务逻辑
            //拒绝消息,false消息丢弃
            channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            //拒绝消息,拒绝指定了delivery_tag的所有未确认的消息,false不回队列
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
        }

4.工具测试

postman调用生产消息(模拟生产者发送消息到队列,消费者消费队列消息):

python rabbitmq配置文件 rabbitmq配置详解_python rabbitmq配置文件

消费者接收到的消息为:

python rabbitmq配置文件 rabbitmq配置详解_发送消息_02


总结

rabbitmq其它类型用法只是绑定交换机和队列时有一定的区别,重点在于生产者消息发送之后,消费者是否消费成功,以及消息重复消费时如何处理。

此种配置是集成springboot中,如果你的代码中需要连接的交换机和队列不存在,将自动创建。
rabbitMq的重点在于消息如何不重复消费,消费失败的消息如何处理,以及多消费者消息如何不重复消费