RabbitMQ部署和Springboot整合


目录:

  1. RabbitMQ的Mac部署
  2. Springboot整合RabbitMQ

RabbitMQ的Mac部署

  • 安装

    brew install rabbitmq

    安装目录在/usr/local/Cellar/rabbitmq,我安装的是3.9.13版本,在其目录下面有3.9.13文件夹

  • 进入sbin目录

    cd /usr/local/Cellar/rabbitmq/3.9.13/sbin
  • 安装web控制台

    ./rabbitmq-plugins enable rabbitmq_management
  • 启动RabbitMQ服务

    • 后台启动

      brew service start rabbitmq
    • 当前窗口启动

      ./rabbitmq-server  
  • 登录web控制台

    默认账户名和密码都是guest

Springboot整合RabbitMQ

pom依赖

<!--集成消息队列-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

YAML配置文件

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    virtual-host: /

Config类

  • 枚举类

    package com.macro.mall.portal.domain;
    
    import lombok.Getter;
    
    /**
     * 消息队列枚举类
     * Created by macro on 2018/9/14.
     */
    @Getter
    public enum QueueEnum {
        /**
         * 消息通知队列
         */
        QUEUE_ORDER_CANCEL("mall.order.direct", "mall.order.cancel", "mall.order.cancel"),
        /**
         * 消息通知ttl队列
         */
        QUEUE_TTL_ORDER_CANCEL("mall.order.direct.ttl", "mall.order.cancel.ttl", "mall.order.cancel.ttl");
    
        /**
         * 交换名称
         */
        private String exchange;
        /**
         * 队列名称
         */
        private String name;
        /**
         * 路由键
         */
        private String routeKey;
    
        QueueEnum(String exchange, String name, String routeKey) {
            this.exchange = exchange;
            this.name = name;
            this.routeKey = routeKey;
        }
    }
    
  • RabbitMqConfig配置类

    package com.macro.mall.portal.config;
    
    import com.macro.mall.portal.domain.QueueEnum;
    import org.springframework.amqp.core.*;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * 消息队列相关配置
     * Created by macro on 2018/9/14.
     */
    @Configuration
    public class RabbitMqConfig {
    
        /**
         * 订单消息实际消费队列所绑定的交换机
         */
        @Bean
        DirectExchange orderDirect() {
            return (DirectExchange) ExchangeBuilder
                    .directExchange(QueueEnum.QUEUE_ORDER_CANCEL.getExchange())
                    .durable(true)
                    .build();
        }
    
        /**
         * 订单延迟队列队列所绑定的交换机
         */
        @Bean
        DirectExchange orderTtlDirect() {
            return (DirectExchange) ExchangeBuilder
                    .directExchange(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange())
                    .durable(true)
                    .build();
        }
    
        /**
         * 订单实际消费队列
         */
        @Bean
        public Queue orderQueue() {
            return new Queue(QueueEnum.QUEUE_ORDER_CANCEL.getName());
        }
    
        /**
         * 订单延迟队列(死信队列)
         */
        @Bean
        public Queue orderTtlQueue() {
            return QueueBuilder
                    .durable(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName())
                    .withArgument("x-dead-letter-exchange", QueueEnum.QUEUE_ORDER_CANCEL.getExchange())//到期后转发的交换机
                    .withArgument("x-dead-letter-routing-key", QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey())//到期后转发的路由键
                    .build();
        }
    
        /**
         * 将订单队列绑定到交换机
         */
        @Bean
        Binding orderBinding(DirectExchange orderDirect,Queue orderQueue){
            return BindingBuilder
                    .bind(orderQueue)
                    .to(orderDirect)
                    .with(QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey());
        }
    
        /**
         * 将订单延迟队列绑定到交换机
         */
        @Bean
        Binding orderTtlBinding(DirectExchange orderTtlDirect,Queue orderTtlQueue){
            return BindingBuilder
                    .bind(orderTtlQueue)
                    .to(orderTtlDirect)
                    .with(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey());
        }
    
    }

生产者

这里恰好使用死信队列实现了延时消息。

package com.macro.mall.portal.component;

import com.macro.mall.portal.domain.QueueEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 取消订单消息的生产者
 * Created by macro on 2018/9/14.
 */
@Component
public class CancelOrderSender {
    private static Logger LOGGER =LoggerFactory.getLogger(CancelOrderSender.class);
    @Autowired
    private AmqpTemplate amqpTemplate;

    public void sendMessage(Long orderId,final long delayTimes){
        //给延迟队列发送消息
        /**
         * jason 20220225:
         * 这里要延时delayTimes发送消息,所以先放到死信队列里面
         * 到期后消息会从死信队列进入订单取消队列QUEUE_ORDER_CANCEL,由消费者消费
         */
        amqpTemplate.convertAndSend(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange(), QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey(), orderId, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //给消息设置延迟毫秒值
                message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
                return message;
            }
        });
        LOGGER.info("send orderId:{}",orderId);
    }
}

消费者

package com.macro.mall.portal.component;

import com.macro.mall.portal.service.OmsPortalOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 取消订单消息的消费者
 * Created by macro on 2018/9/14.
 */
@Component
public class CancelOrderReceiver {
    private static Logger LOGGER =LoggerFactory.getLogger(CancelOrderReceiver.class);
    @Autowired
    private OmsPortalOrderService portalOrderService;
  
    @RabbitHandler
  	@RabbitListener(queues = "mall.order.cancel") //注意这里监听位置,要加在方法上!!!
    public void handle(Long orderId){
        portalOrderService.cancelOrder(orderId);
        LOGGER.info("process orderId:{}",orderId);
    }
}

文章作者: 小小千千
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小千千 !
评论
  目录