SpringBoot集成RabbitMq简单应用

                           SpringBoot集成RabbitMq简单应用

  • maven配置
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
  • application配置文件
#####rabbitmq####
spring.application.name=springboot-rabbitmq
spring.rabbitmq.addresses=*****
spring.rabbitmq.port=5672
spring.rabbitmq.username=****
spring.rabbitmq.password=****
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.virtual-host=/
spring.rabbitmq.queue.prefix.name=lyh-test

#采用手動應答
spring.rabbitmq.listener.simple.acknowledge-mode=MANUAL
spring.rabbitmq.listener.simple.retry.enabled=true

logging.level.root=info
  • 启动类
package com.lyh.mq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MqApplication {

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

}
  • Exchange 类型

Exchange分发消息时根据类型的不同分发策略有区别,目前共四种类型:direct、fanout、topic、headers 。下面只讲前三种模式。

1.Direct模式

消息中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器就将消息发到对应的队列中。路由键与队列名完全匹配

2.Topic模式

topic 交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号“#”和符号“*”。#匹配0个或多个单词,*匹配一个单词。

3.Fanout模式

每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。fanout 交换器不处理路由键,只是简单的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。fanout 类型转发消息是最快的。
 

  • 路由模式--direct

1:队列配置类

package com.lyh.mq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class MqConfig {

    private static Logger log = LoggerFactory.getLogger(MqConfig.class);

    @Resource
    RabbitTemplate rabbitTemplate;


    @Bean
    public AmqpTemplate amqpTemplate() {
//          使用jackson 消息转换器
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setEncoding("UTF-8");
//        开启returncallback     yml 需要 配置    publisher-returns: true
        rabbitTemplate.setMandatory(true);
//        rabbitTemplate.setConnectionFactory(new CachingConnectionFactory());
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            String correlationId = message.getMessageProperties().getCorrelationId();

            log.error("消息:{} 发送失败, 应答码:{} 原因:{} 交换机: {}  路由键: {}", correlationId, replyCode, replyText, exchange, routingKey);
        });

        //        消息确认  yml 需要配置   publisher-returns: true
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.debug("消息发送到exchange成功,id: {}", correlationData.getId());
            } else {
                log.error("消息发送到exchange失败,原因: {}", cause);
            }
        });
        return rabbitTemplate;
    }

    //TODO:基本消息模型构建
    @Bean
    public DirectExchange basicExchange(){
        return new DirectExchange("basicExchange", true,false);
    }

    @Bean(name = "basicQueue")
    public Queue basicQueue(){
        return new Queue("basicQueue", true);
    }

    @Bean
    public Binding basicBinding(){
        return BindingBuilder.bind(basicQueue()).to(basicExchange()).with("basicKey");
    }



  }

2:发送者类

package com.lyh.mq;




import com.alibaba.fastjson.JSONObject;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@RestController
public class RabbitProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @RequestMapping("directSend")
    public void directSend() {
        Date date = new Date();
        String dateString = new SimpleDateFormat("YYYY-mm-DD hh:MM:ss").format(date);
        System.out.println("[string] send msg:" + dateString);
        // 第一个参数为刚刚定义的队列名称
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("basicExchange","basicKey",dateString,correlationData);
    }

   
}

3:接收者类

package com.lyh.mq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

@Service
public class RabbitConsumer {
    private static final Logger log= LoggerFactory.getLogger(RabbitConsumer.class);

    /**
     * 监听消费消息
     * @param message
     */
    @RabbitListener(queues ="basicQueue")
    public void consumeMessage(@Payload byte[] message){
        try {
            //TODO:接收String
            String result=new String(message,"UTF-8");
            log.info("接收String消息: {} ",result);
        }catch (Exception e){
            log.error("监听消费消息 发生异常: ",e.fillInStackTrace());
        }
    }


  

}

4:访问http://localhost:8080/directSend,查看日志输出

 INFO 8772 --- [io-8080-exec-10] com.lzc.rabbitmq.config.Sender           : 【sendDirectQueue已发送消息】
  INFO 8772 --- [cTaskExecutor-1] com.lzc.rabbitmq.config.Receiver         : 【receiverDirectQueue监听到消息】User(userId=123456, name=lizhencheng)

注意:发送者与接收者的Queue名字一定要相同,否则接收收不到消息

 

  • Fanout模式

1:队列配置类

package com.lyh.mq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class MqConfig {

    private static Logger log = LoggerFactory.getLogger(MqConfig.class);

    @Resource
    RabbitTemplate rabbitTemplate;


    @Bean
    public AmqpTemplate amqpTemplate() {
//          使用jackson 消息转换器
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setEncoding("UTF-8");
//        开启returncallback     yml 需要 配置    publisher-returns: true
        rabbitTemplate.setMandatory(true);
//        rabbitTemplate.setConnectionFactory(new CachingConnectionFactory());
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            String correlationId = message.getMessageProperties().getCorrelationId();

            log.error("消息:{} 发送失败, 应答码:{} 原因:{} 交换机: {}  路由键: {}", correlationId, replyCode, replyText, exchange, routingKey);
        });

        //        消息确认  yml 需要配置   publisher-returns: true
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.debug("消息发送到exchange成功,id: {}", correlationData.getId());
            } else {
                log.error("消息发送到exchange失败,原因: {}", cause);
            }
        });
        return rabbitTemplate;
    }

    //TODO:基本消息模型构建
    @Bean
    public DirectExchange basicExchange(){
        return new DirectExchange("basicExchange", true,false);
    }

    @Bean(name = "basicQueue")
    public Queue basicQueue(){
        return new Queue("basicQueue", true);
    }

    @Bean
    public Binding basicBinding(){
        return BindingBuilder.bind(basicQueue()).to(basicExchange()).with("basicKey");
    }

 @Bean("fanoutExchange")
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange",true,false);
    }

    @Bean("fanout01")
    public Queue fanout01(){
        return QueueBuilder.durable("fanout01").build();
    }

    @Bean("fanout02")
    public Queue fanout02(){
        return QueueBuilder.durable("fanout02").build();
    }

    @Bean
    public Binding fanoutBind01(){
        return BindingBuilder.bind(fanout01()).to(fanoutExchange());
    }

    @Bean
    public Binding fanoutBind012(){
        return BindingBuilder.bind(fanout02()).to(fanoutExchange());
    }

  }

2:发送者类

package com.lyh.mq;




import com.alibaba.fastjson.JSONObject;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@RestController
public class RabbitProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @RequestMapping("directSend")
    public void directSend() {
        Date date = new Date();
        String dateString = new SimpleDateFormat("YYYY-mm-DD hh:MM:ss").format(date);
        System.out.println("[string] send msg:" + dateString);
        // 第一个参数为刚刚定义的队列名称
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("basicExchange","basicKey",dateString,correlationData);
    }

      @RequestMapping("fanoutSend")
    public void fanoutSend() {
        Date date = new Date();
        String dateString = new SimpleDateFormat("YYYY-mm-DD hh:MM:ss").format(date);
        System.out.println("[string] send msg:" + dateString);
        // 第一个参数为刚刚定义的队列名称
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("fanoutExchange","",dateString,correlationData);
    }

}

3:接收者类

package com.lyh.mq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

@Service
public class RabbitConsumer {
    private static final Logger log= LoggerFactory.getLogger(RabbitConsumer.class);

    /**
     * 监听消费消息
     * @param message
     */
    @RabbitListener(queues ="basicQueue")
    public void consumeMessage(@Payload byte[] message){
        try {
            //TODO:接收String
            String result=new String(message,"UTF-8");
            log.info("接收String消息: {} ",result);
        }catch (Exception e){
            log.error("监听消费消息 发生异常: ",e.fillInStackTrace());
        }
    }


    /**
     * 监听消费消息
     * @param message
     */
    @RabbitListener(queues ="fanout01")
    public void consumeMessage1(@Payload byte[] message){
        try {
            //TODO:接收String
            String result=new String(message,"UTF-8");
            log.info("接收String1消息: {} ",result);
        }catch (Exception e){
            log.error("监听消费消息 发生异常: ",e.fillInStackTrace());
        }
    }

    /**
     * 监听消费消息
     * @param message
     */
    @RabbitListener(queues ="fanout02")
    public void consumeMessage2(@Payload byte[] message){
        try {
            //TODO:接收String
            String result=new String(message,"UTF-8");
            log.info("接收String2消息: {} ",result);
        }catch (Exception e){
            log.error("监听消费消息 发生异常: ",e.fillInStackTrace());
        }
    }

}

4:访问http://localhost:8080/fanoutSend

查看日志输出,由日志输出可以看出,两个接收者都接收到了消息,因为交换机fanoutExchange绑定了两个队列。

  • Topic模式

1:队列配置类

package com.lyh.mq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class MqConfig {

    private static Logger log = LoggerFactory.getLogger(MqConfig.class);

    @Resource
    RabbitTemplate rabbitTemplate;


    @Bean
    public AmqpTemplate amqpTemplate() {
//          使用jackson 消息转换器
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setEncoding("UTF-8");
//        开启returncallback     yml 需要 配置    publisher-returns: true
        rabbitTemplate.setMandatory(true);
//        rabbitTemplate.setConnectionFactory(new CachingConnectionFactory());
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            String correlationId = message.getMessageProperties().getCorrelationId();

            log.error("消息:{} 发送失败, 应答码:{} 原因:{} 交换机: {}  路由键: {}", correlationId, replyCode, replyText, exchange, routingKey);
        });

        //        消息确认  yml 需要配置   publisher-returns: true
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.debug("消息发送到exchange成功,id: {}", correlationData.getId());
            } else {
                log.error("消息发送到exchange失败,原因: {}", cause);
            }
        });
        return rabbitTemplate;
    }

    //TODO:基本消息模型构建
    @Bean
    public DirectExchange basicExchange(){
        return new DirectExchange("basicExchange", true,false);
    }

    @Bean(name = "basicQueue")
    public Queue basicQueue(){
        return new Queue("basicQueue", true);
    }

    @Bean
    public Binding basicBinding(){
        return BindingBuilder.bind(basicQueue()).to(basicExchange()).with("basicKey");
    }

 @Bean("fanoutExchange")
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange",true,false);
    }

    @Bean("fanout01")
    public Queue fanout01(){
        return QueueBuilder.durable("fanout01").build();
    }

    @Bean("fanout02")
    public Queue fanout02(){
        return QueueBuilder.durable("fanout02").build();
    }

    @Bean
    public Binding fanoutBind01(){
        return BindingBuilder.bind(fanout01()).to(fanoutExchange());
    }

    @Bean
    public Binding fanoutBind012(){
        return BindingBuilder.bind(fanout02()).to(fanoutExchange());
    }
 /**
     * Topic模式
     * @return
     */
    public static final String TOPIC_QUEUE1 = "topic.queue1";
    public static final String TOPIC_QUEUE2 = "topic.queue2";
    public static final String TOPIC_EXCHANGE = "topic.exchange";

    @Bean
    public Queue topicQueue1() {
        return new Queue(TOPIC_QUEUE1);
    }
    @Bean
    public Queue topicQueue2() {
        return new Queue(TOPIC_QUEUE2);
    }
    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange(TOPIC_EXCHANGE);
    }
    @Bean
    public Binding topicBinding1() {
        return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("lzc.message");
    }
    @Bean
    public Binding topicBinding2() {
        return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("lzc.#");
    }

  }

2:发送者类

package com.lyh.mq;




import com.alibaba.fastjson.JSONObject;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@RestController
public class RabbitProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @RequestMapping("directSend")
    public void directSend() {
        Date date = new Date();
        String dateString = new SimpleDateFormat("YYYY-mm-DD hh:MM:ss").format(date);
        System.out.println("[string] send msg:" + dateString);
        // 第一个参数为刚刚定义的队列名称
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("basicExchange","basicKey",dateString,correlationData);
    }

      @RequestMapping("fanoutSend")
    public void fanoutSend() {
        Date date = new Date();
        String dateString = new SimpleDateFormat("YYYY-mm-DD hh:MM:ss").format(date);
        System.out.println("[string] send msg:" + dateString);
        // 第一个参数为刚刚定义的队列名称
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("fanoutExchange","",dateString,correlationData);
    }

@RequestMapping("sendTopic")
    public void sendTopic() {
        Date date = new Date();
        String dateString = new SimpleDateFormat("YYYY-mm-DD hh:MM:ss").format(date);
        System.out.println("[string] send msg:" + dateString);
        // 第一个参数为刚刚定义的队列名称
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        this.rabbitTemplate.convertAndSend(MqConfig.TOPIC_EXCHANGE, "lzc.message", dateString );
        this.rabbitTemplate.convertAndSend(MqConfig.TOPIC_EXCHANGE, "lzc.lzc", dateString);

    }

}

3:接收者类

package com.lyh.mq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

@Service
public class RabbitConsumer {
    private static final Logger log= LoggerFactory.getLogger(RabbitConsumer.class);

    /**
     * 监听消费消息
     * @param message
     */
    @RabbitListener(queues ="basicQueue")
    public void consumeMessage(@Payload byte[] message){
        try {
            //TODO:接收String
            String result=new String(message,"UTF-8");
            log.info("接收String消息: {} ",result);
        }catch (Exception e){
            log.error("监听消费消息 发生异常: ",e.fillInStackTrace());
        }
    }


    /**
     * 监听消费消息
     * @param message
     */
    @RabbitListener(queues ="fanout01")
    public void consumeMessage1(@Payload byte[] message){
        try {
            //TODO:接收String
            String result=new String(message,"UTF-8");
            log.info("接收String1消息: {} ",result);
        }catch (Exception e){
            log.error("监听消费消息 发生异常: ",e.fillInStackTrace());
        }
    }

    /**
     * 监听消费消息
     * @param message
     */
    @RabbitListener(queues ="fanout02")
    public void consumeMessage2(@Payload byte[] message){
        try {
            //TODO:接收String
            String result=new String(message,"UTF-8");
            log.info("接收String2消息: {} ",result);
        }catch (Exception e){
            log.error("监听消费消息 发生异常: ",e.fillInStackTrace());
        }
    }

 @RabbitListener(queues = MqConfig.TOPIC_QUEUE1)
    public void receiveTopic1(@Payload byte[] message) {
        log.info("【receiveTopic1监听到消息】" + message.toString());
    }
    @RabbitListener(queues = MqConfig.TOPIC_QUEUE2)
    public void receiveTopic2(@Payload byte[] message) {
        log.info("【receiveTopic2监听到消息】" + message.toString());
    }

}

4:访问http://localhost:8080/sendTopic

查看日志输出,由日志记录可以看出lzc.message可以被receiveTopic1和receiveTopic2所接收,而lzc.lzc只能被receiveTopic2接收。

源码地址

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值