RabbitMQ与SpringBoot整合实战

本文介绍如何在SpringBoot项目中集成RabbitMQ,包括引入依赖、配置参数、实现消息确认与返回机制,以及使用@RabbitListener注解进行消费端配置。

SpringBoot整合RabbitMQ
SpringBoot与RabbitMQ集成非常筒単,不需要做任何的额外设置只需要两步即可:
step1:引入相关依赖:spring-boot-starter-amqp

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


step2:対application.properties迸行配置

# rabbitmq连接基本配置
spring.rabbitmq.addresses=192.168.0.113:5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
spring.rabbitmq.connection-timeout=15000

# 开启发布者确认机制、确认消息是否正确到达Exchange中、ConfirmCallback是一个回调接口,消息发送到 Broker 后触发回调
spring.rabbitmq.publisher-confirms=true
# 开启发布者返回模式、通过实现 ReturnCallback 接口,启动消息失败返回,此接口是在交换器路由不到队列时触发回调
spring.rabbitmq.publisher-returns=true
# 配合return机制使用,表示接收路由不可达的消息
spring.rabbitmq.template.mandatory=true
#如果消费端异常直接丢弃消息
spring.rabbitmq.listener.simple.default-requeue-rejected: true
#消费者消息确认(NONE:自动确认、AUTO:根据情况确认、MANUAL:手动确认)
spring.rabbitmq.listener.direct.acknowledge-mode=MANUAL

step3:生产者发布消息到队列,如果exchange为空字符串,则默认发送到默认交换机(AMQP defalut)默认交换机的绑定是隐式的,每个新增队列都会自动绑定到默认交换机,绑定键(binding key)即队列名称

rabbitTemplate.convertAndSend(
            request.getExchange(),
            request.getRoutingKey(), request.getContent(), m -> {
                MessageProperties properties = m.getMessageProperties();
                properties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                properties.setPriority(request.getPriority());
                Map<String, Object> headers = m.getMessageProperties().getHeaders();
                headers.putAll(Beans.beanToMap(request));
                return m;
            }, new CorrelationData(request.getMessageId())
        );

发布消息前可以把消息先存到数据库中、如果消息消费失败,直接丢弃,把数据库中记录状态

更改未失败状态,通过定时器重新发送

4种交换机类型:

        direct exchange 通过 routerkey精准匹配
        topic exchange routingkey可以有通配符 * #
       fanout exchange 此exchange的路由规则很简单直接将消息路由到所有绑定的队列中,无须                 对消息的routingkey进行匹配操作
       header exchange 其路由的规则是根据header来判断

step4:消费消息
 

@Component
@RabbitListener(queues = MessageTypeDefinition.COSTING_CARRY_OVER, containerFactory = "customContainerFactory")
public class ClosingCarryOverMq {

    @RabbitHandler
    public void handler(
        @Payload String message, Channel channel,
        @Headers Map<String, Object> headers
    ) {
        // 消息确认
        Long tag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        try{
            //取发送的信息
             Map<String,Object> map = new HashMap<String,Object>(){{
                putAll(headers);
            }};
            map.put("content",null);

            SendMessageRequest header =        ObjectMapperUtils.convertMapToBean(SendMessageRequest.class,map);
            Long infoId = Long.valueOf(header.getKeywords());
            //处理业务逻辑
        }catch(Exception e){
              //消费失败数据库表message_logs消息记录状态为处理失败,通过定时器重发
        }finally {
            /**
              *ack种类
              *1.手动确认、消息处理成功
              *channel.basicAck(tag, false);
              *2.拒绝,消息重回队列
              *channel.basicNack(tag, false, true);
              *3.拒绝,删除消息
              *channel.basicNack(tag, false, false);
             **/
             /**
             * basicAck 方法需要传递两个参数
             * deliveryTag(唯一标识 ID):当一个消费者向 RabbitMQ 注册后,
             *会建立起一个Channel ,RabbitMQ 会用 basic.deliver 方法向消费者推送消息,
             *这个方法携带了一个 delivery tag, 它代表了 RabbitMQ 向该 Channel 投递的
             *这条消息的唯一标识 ID,是一个单调递增的正整数,delivery tag 的范围仅限于 Channel
             * multiple:为了减少网络流量,手动确认可以被批处理,当该参数为 true 时,
             *则可以一次 性确认 delivery_tag 小于等于传入值的所有消息
             * 
             *basicNack方法需要传递三个参数
             * deliveryTag(唯一标识 ID):上面已经解释了。
             * multiple:上面已经解释了。
             * requeue: true :重回队列,false :丢弃,我们在nack方法中必须设置 false,
             *否则重 发没有意义。
             */

            if (headers.get("error") != null) {
                // 错误的消息, 否认消息, 重回队列
                try {
                    channel.basicNack(tag, false, true);
                } catch (IOException e1) {
                    logger.error(e1.getLocalizedMessage(), e1);
                }
            }
            // 确认消息
            try {
                channel.basicAck(tag, false);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }  
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值