Rabbitmq整合SpringBoot

1、导入pom

<!--引入 rabbit依赖 amqp 高级消息队列协议-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2、配置类

#配置rabbitmq的 主机、端口、用户名、密码
spring.rabbitmq.host=192.168.56.10
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
#账号密码配置类默认都是guest,此处可不配置
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

#开启发送端确认
spring.rabbitmq.publisher-confirms=true
#开启发送端消息抵达队列的确认
spring.rabbitmq.publisher-returns=true
#只要抵达队列,以异步发送优先回调我们这个 returnConfirm
spring.rabbitmq.template.mandatory=true

#手动ack消息
spring.rabbitmq.listener.simple.acknowledge-mode=manual

3、主启动开启rabbit功能

/**
 * 使用rabbitmq
 * 1、引入amqp 场景pom,RabbitAutoConfiguration 自动生效
 * 2、给容器中自动配置了
 *      RabbitTemplate、AmqpAdmin、CacheConnectionFactory
 * 3、配置文件,所有的属性绑定
 *      @ConfigurationProperties(prefix = "spring.rabbitmq")
 * 4、@EnableRabbit  开启功能
 * 5、监听消息,使用 @RabbitListener,必须有 @EnableRabbit
 * @RabbitListener:类+方法(监听哪些队列即可)
 * @RabbitHandler:标在方法上(重载区分不同的消息)
 */
@EnableRabbit
@EnableDiscoveryClient
@MapperScan("com.lian.gulimall.order.dao")
@SpringBootApplication
public class GulimallOrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallOrderApplication.class, args);
    }

}

4、AmqpAdmin

创建交换机和队列,并将队列和交换机绑定

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class GulimallOrderApplicationTests {

    @Autowired
    AmqpAdmin amqpAdmin;

    /**
     * 1、如何创建 Exchange、Queue、Binding
     *    使用AmqpAdmin 进行创建
     * 2、如何收发消息
     */
    @Test
    public void createExchange(){
        //创建一个 direct 直接交换机
        DirectExchange directExchange = new DirectExchange("hello-java-exchange",true,false);
        //声明一个交换机
        amqpAdmin.declareExchange(directExchange);
        log.info("exchange[{}]创建成功","hello-java-exchange");
        //声明一个队列
        Queue queue = new Queue("hello-java-queue",true,false,false,null);
        amqpAdmin.declareQueue(queue);
        log.info("queue[{}]创建成功","hello-java-queue");
        //声明一个绑定器
        /**
         * String destination, 目的地
         * Binding.DestinationType destinationType, 目的地类型
         * String exchange, 交换机
         * String routingKey, 路由键
         * Map<String, Object> arguments)  自定义参数
         */
        Binding binding = new Binding(
                "hello-java-queue",
                Binding.DestinationType.QUEUE,
                "hello-java-exchange",
                "hello.java",
                null);
        //队列绑定交换机
        amqpAdmin.declareBinding(binding);
        log.info("binding[{}]创建成功","hello-java-binding");
    }

}

5、RabbitmqTemplate

发送消息

	@Autowired
    RabbitTemplate rabbitTemplate;

    @Test
    public void sendMessage(){
        /**
         * send:原生的send方法,需要发送一个Message类型的对象
         * convertAndSend: 将对象转为字节流,传给rabbitmq(推荐)
         */
        //String msg = "hello pidan";
        //发送消息如果是对象,因为要将对象转为字节传输,对象必须实现序列化接口Serializable
        OrderReturnReasonEntity msg = new OrderReturnReasonEntity();
        msg.setId(1L);
        msg.setCreateTime(new Date());
        msg.setName("皮皮");
        /**
         * 1、交换机,生产者——broker(交换机绑定队列)——消费者
         * 2、routingKey ,交换机和队列用 路由key绑定
         * 3、要发送的消息
         */
        rabbitTemplate.convertAndSend(
                "hello-java-exchange",
                "hello.java",
                msg);
        log.info("消息发送完成{}",msg);
    }

返回结果
在这里插入图片描述
配置 MessageConverter 消息转换类

import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyRabbitConfig {

    //消息类型转换器,将对象转为json格式
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

}

在这里插入图片描述

6、RabbitListener和RabbitHandler

接收消息

	/**
     * rabbitmq 接收消息
     * 只要这个队列里有消息,就可以收到消息
     */
    @RabbitListener(queues = "hello-java-queue")
    public void receiveMessage(Message message, OrderReturnReasonEntity content, Channel channel){
        //消息体
        byte[] body = message.getBody();
        System.out.println("消息体为" +body);
        Object msg = JSON.parseObject(body, OrderReturnReasonEntity.class);
        System.out.println("msg 是:" +msg);
        //参数里填写 OrderReturnReasonEntity类型的对象,和json自动转对象的功能一样
        System.out.println("content 是,功能和json一样,spring自动生成" +content);
        //消息体,包含消息头等内容
        MessageProperties properties = message.getMessageProperties();
        System.out.println("消息头信息"+ properties);
        //类型为class org.springframework.amqp.core.Message
        System.out.println("接收到的消息内容"+ message + "类型为"+message.getClass());

    }

rabbitHandler

@RabbitListener(queues = "hello-java-queue")
@Service("orderItemService")
public class OrderItemServiceImpl extends ServiceImpl<OrderItemDao, OrderItemEntity> implements OrderItemService {

/**
     * rabbitmq 接收消息
     * 只要这个队列里有消息,就可以收到消息
     */
    //@RabbitListener(queues = "hello-java-queue")
    @RabbitHandler
    public void receiveMessage(Message message, OrderReturnReasonEntity content, Channel channel){
        //消息体
        byte[] body = message.getBody();
        System.out.println("消息体为" +body);
        Object msg = JSON.parseObject(body, OrderReturnReasonEntity.class);
        System.out.println("msg 是:" +msg);
        //参数里填写 OrderReturnReasonEntity类型的对象,和json自动转对象的功能一样
        System.out.println("content 是,功能和json一样,spring自动生成" +content);
        //消息体,包含消息头等内容
        MessageProperties properties = message.getMessageProperties();
        System.out.println("消息头信息"+ properties);
        //类型为class org.springframework.amqp.core.Message
        System.out.println("接收到的消息内容"+ message + "类型为"+message.getClass());

    }
}

7、发送端确认

保证消息不丢失,可靠抵达,可以使用事务消息,性能下降250倍,为此引入确认 机制
• publisher confirmCallback 确认模式
• publisher returnCallback 未投递到 queue 退回模式
• consumer ack机制
在这里插入图片描述

1、配置文件

#配置rabbitmq的 主机、端口、用户名、密码
spring.rabbitmq.host=192.168.56.10
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
#账号密码配置类默认都是guest,此处可不配置
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

#开启发送端确认
spring.rabbitmq.publisher-confirms=true
#开启发送端消息抵达队列的确认
spring.rabbitmq.publisher-returns=true
#只要抵达队列,以异步发送优先回调我们这个 returnConfirm
spring.rabbitmq.template.mandatory=true

#手动ack消息
spring.rabbitmq.listener.simple.acknowledge-mode=manual

2、配置类

package com.lian.gulimall.order.config;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class MyRabbitConfig {

    @Autowired
    RabbitTemplate rabbitTemplate;

    /**
     * 使用json序列化机制,进行消息转换
     * 消息类型转换器,将对象转为json格式
     */
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    /**
     * MyRabbitConfig 对象创建完成之后,执行此方法
     */
    @PostConstruct
    public void initRabbitTemplate(){
        //设置确认回调
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {

            /**
             *
             * @param correlationData  当前消息的唯一关联数据
             * @param ack  消息是否成功收到
             * @param cause  失败的原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("correlationData: "+correlationData+"ack: "+ack+"cause: "+cause);
            }
        });


        /**
         * 设置消息抵达队列的确认回调
         */
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {

            /**
             * down 下来源代码后,参数就有名字了,方便理解
             * 回退消息例子是 交换机收到消息,但是队列没有收到消息,消费者无法接收到
             * @param message  投递失败的消息详细信息
             * @param replyCode 回复的状态码
             * @param replyText 回复的文本内容
             * @param exchange 当时这个消息发送给哪个交换机
             * @param routingKey 当时这个消息用哪个路由键
             */
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                System.out.println("message: "+message+"replyCode: "+replyCode+"replyText: "+replyText+"exchange: "+exchange+"routingKey: "+routingKey);
            }
        });
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值