RabbitMQ-SpringBoot2

1.依赖引用

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

    <version>2.3.12.RELEASE</version>
</dependency>

2.配置文件

spring:
  rabbitmq:
    host: 192.168.2.17
    port: 5672
    username: admin
    password: admin

    publisher-confirm-type: correlated

3.死信队列配置类

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
public class TtlConfig {

    public static final String dead_exchange = "deadExchange";
    public static final String dead_queue = "deadQueue";

    public static final String dead_key = "deadKey";

    public static final String normal_exchange = "normalExchange";

    String normal_queue = "normalQueue";
    String normal_key = "normalKey";

    @Bean("deadQueue")
    public  Queue deadQueue()
    {
        Queue queue = new Queue(dead_queue, false, false, false, null);
        return queue;
    }
    @Bean("deadExchange")
    public DirectExchange deadExchange()
    {
        DirectExchange exchange = new DirectExchange(dead_exchange, false, false);
        return exchange;
    }

    @Bean("deadBinding")
    public Binding deadBinding(@Qualifier("deadQueue") Queue queue,
                                 @Qualifier("deadExchange") DirectExchange exchange)
    {
        Binding binding = BindingBuilder.bind(queue).to(exchange).with(dead_key);
        return binding;
    }

    @Bean("normalQueue")
    public Queue normalQueue()
    {
        Map<String, Object> params = new HashMap<>();

        //正常队列设置死信交换机 参数 key 是固定值
        params.put("x-dead-letter-exchange", dead_exchange);
        //正常队列设置死信 routing-key 参数 key 是固定值
        params.put("x-dead-letter-routing-key", dead_key);
        params.put("x-max-length", 6); //最大长度
        params.put("x-message-ttl", 5000);  // 毫秒单位, 这种是在队列时限制延迟时间

        Queue queue = new Queue(normal_queue, false, false, false, params);
        return queue;
    }

    @Bean("normalExchange")
    public DirectExchange normalExchange()
    {
        DirectExchange exchange = new DirectExchange(normal_exchange, false, false);
        return exchange;
    }

    @Bean("normalBinding")
    public Binding normalBinding(@Qualifier("normalQueue") Queue queue,
                                 @Qualifier("normalExchange") DirectExchange exchange)
    {
        Binding binding = BindingBuilder.bind(queue).to(exchange).with(normal_key);
        return binding;
    }
}

4.消费者

   4.1 自动消费
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
 
@Slf4j
@Component
public class ClusterConsumer {

    @RabbitListener(queues = ClusterConfig.queueName)
    public void receiveMsg(Message message)
    {
        String msg = new String(message.getBody());
        log.info("[ClusterConsumer] 收到消息:{}", msg);
    }

}
  4.2 手动消费

    1) 监听

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;
 
@Component
public class DeadQueueAwareConsumer implements ChannelAwareMessageListener {

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {

        long deliveryTag =  message.getMessageProperties().getDeliveryTag();
        channel.basicAck(deliveryTag, false);
        System.out.println("DeadQueueAwareConsumer->" + deliveryTag);

        //basicNack
    }
}

    2) 工厂

import com.demo.mq.config.TtlConfig;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DeadQueueAwareListenerConfig {

    @Autowired
    private DeadQueueAwareConsumer deadQueueAwareConsumer;

    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer()
    {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setConcurrentConsumers(1);
        container.setMaxConcurrentConsumers(1);
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL); // RabbitMQ默认是自动确认,这里改为手动确认消

        container.setQueueNames(TtlConfig.dead_queue);
        container.setMessageListener(this.deadQueueAwareConsumer);

        return container;
    }
}

    3) 

5.生产者

  5.1 异步类

import com.demo.mq.config.TtlConfig;
import org.springframework.amqp.core.Message;
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.Component;

import javax.annotation.PostConstruct;
 
@Component
public class MessageProducer implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    private Integer id = 0;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init()
    {
        /**
         * true:
         * 交换机无法将消息进行路由时,会将该消息返回给生产者
         * false:
         * 如果发现消息无法进行路由,则直接丢弃
         */

        this.rabbitTemplate.setMandatory(true);
        this.rabbitTemplate.setConfirmCallback(this);
        this.rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 交换机不管是否收到消息的一个回调方法
     * CorrelationData
     * 消息相关数据
     * ack
     * 交换机是否收到消息
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {

        String msg = "";
        String id = correlationData != null ? correlationData.getId() : "";
        if (ack) {
            msg = "交换机已经收到 id 为:" + id + "的消息";
        } else {
            msg = "交换机还未收到 id 为:" + id + "消息,由于原因: " + cause;
        }

        System.out.println(msg);
    }

    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {

        String msg = "消 息 "+new String(message.getBody())+ ", 被 交 换 机 "+exchange+ "退 回 , 退 回 原 因 :"+replyText+", 路 由 key:" + routingKey;
        System.out.println(msg);
    }

    public void sendMessage(String message) {

        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(this.id.toString());
        rabbitTemplate.convertAndSend(TtlConfig.normal_exchange, "normalKey", message,correlationData);
        this.id++;
    }
}

  5.2 使用

@RestController
@RequestMapping("producer")
public class ProducerController {

    @Autowired
    private MessageProducer myCallBack;
    
    @GetMapping("ttl/{id}")
    public void ttl(@PathVariable("id") String id){

        this.myCallBack.sendMessage("info" + id);

    }
}

6.测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wang_peng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值