SpringBoot整合RabbitMq

SpringBoot整合RabbitMq

参考博客:https://blog.csdn.net/qq_33547169/article/details/78124294

1.介绍

1.1 RabbitMQ
MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message
Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开
发中应用非常广泛。RabbitMQ官方地址:http://www.rabbitmq.com/

开发中消息队列通常有如下应用场景:
1、任务异步处理。
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
2、应用程序解耦合
MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合。
市场上还有哪些消息队列?
ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ、Redis。
为什么使用RabbitMQ呢?
1、使得简单,功能强大。
2、基于AMQP协议。
3、社区活跃,文档完善。
4、高并发性能好,这主要得益于Erlang语言。
5、Spring Boot默认已集成RabbitMQ

1.2rabbitmq工作原理
工作原理
组成部分说明如下:
Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue。
Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。
Producer:消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。
消息发布接收流程:
-----发送消息-----
1、生产者和Broker建立TCP连接。
2、生产者和Broker建立通道。
3、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
4、Exchange将消息转发到指定的Queue(队列)

3.安装与使用
1)下载erlang
地址如下:
http://erlang.org/download/otp_win64_20.3.exe
以管理员方式运行此文件,安装。

2)安装RabbitMQ
https://github.com/rabbitmq/rabbitmq-server/releases/tag/v3.7.4

安装完成后可在服务中启动
在这里插入图片描述
当然也可以进入安装目录以命令行的方式启动
在这里插入图片描述
打开浏览器访问rabbitmq若出现这个界面说明可以正常使用了账号密码默认为guest
在这里插入图片描述

2.SpringBoot整合的RabbitMq(Direct模式)

1.首先创建maven工程并引入依赖坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.paic</groupId>
    <artifactId>rabbitmq-producer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

2.创建配置文件

#对于rabbitMQ的支持
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

3.创建一个启动类

package com.paic;

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

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic
 * @ClassName: RabbitMqApplication
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@SpringBootApplication
public class RabbitMqApplication {
    public static void main(String[] args) {
        SpringApplication.run(RabbitMqApplication.class);
    }
}

4.创建一个生产者

package com.paic.producer;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.producer
 * @ClassName: Producer
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Component
public class Producer {
    @Autowired
    private AmqpTemplate rabbitTemplate;

    public void send(){
        String sendMsg = "hello world"+ new Date();
        this.rabbitTemplate.convertAndSend("one2one", sendMsg);
    }
}

5.创建一个消费者

package com.paic.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.consumer
 * @ClassName: Consumer
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Component
@RabbitListener(queues = "one2one")
public class Consumer {
    @RabbitHandler
    public void process(String hello) {
        System.out.println("one2one 消息消费者消费消息  : " + hello);
    }
}

6.创建配置类配置一个队列

package com.paic.config;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.config
 * @ClassName: Config
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Component
public class Config {
    final static String ONE2ONE = "one2one";

    @Bean
    public Queue queueOne2One() {
        return new Queue(ONE2ONE);
    }
}

7.创建一个Controller进行调用

package com.paic.controller;

import com.paic.producer.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.controller
 * @ClassName: One2OneController
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@RestController
public class One2OneController {
    @Autowired
    private Producer oneProducer;

    @RequestMapping("/one2one")
    public String one2OneSend(){
        oneProducer.send();
        return "ok";
    }
}

8.测试
运行启动类然后在浏览器中输入请求路径
在这里插入图片描述
控制台输出如下
在这里插入图片描述
说明这个最简单的一对一的消息生产获取已经实现了
一对多模式与多对多模式与一对一模式区别就在于创建多个生产者、消费者
我们多对多的运行结果,这里创建2个生产者和2个消费者,生产20条消息,发现两个消费者各消费了10条消息
在这里插入图片描述

3.SpringBoot整合的RabbitMq(Topic模式)

1.编写配置类

package com.paic.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.config
 * @ClassName: TopicConfig
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Configuration
public class TopicConfig {

        final static String MESSAGE = "topic.message";
        final static String MESSAGES = "topic.messages";

        @Bean
        public Queue queueMessage() {
            return new Queue(MESSAGE);
        }

        @Bean
        public Queue queueMessages() {
            return new Queue(MESSAGES);
        }

        @Bean
        TopicExchange exchange() {
            return new TopicExchange("exchange");
        }

        /**
         * 将队列topic.message与exchange绑定,binding_key为topic.message,就是完全匹配
         * @param queueMessage
         * @param exchange
         * @return
         */
        @Bean
        Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
            return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
        }

        /**
         * 将队列topic.messages与exchange绑定,binding_key为topic.#,模糊匹配
         * @param queueMessages
         * @param exchange
         * @return
         */
        @Bean
        Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
            return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
        }
}

这里配置了一个完全匹配和一个模糊匹配
2.配置消息生产者

package com.paic.producer;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.producer
 * @ClassName: TopicExchangeProducer
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Component
public class TopicExchangeProducer {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void send() {
        rabbitTemplate.convertAndSend("exchange", "topic.message", "topic.message");
        rabbitTemplate.convertAndSend("exchange", "topic.messages", "topic.messages");
    }
}

3.配置两个消息消费者

package com.paic.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.consumer
 * @ClassName: MessageCustomer
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Component
@RabbitListener(queues = "topic.message")
public class MessageCustomer {

    @RabbitHandler
    public void process(String msg){
        System.out.println("topicexchange message 消费者  : " +msg);
    }
}

@Component
@RabbitListener(queues = "topic.messages")
public class MessagesCustomer {

    @RabbitHandler
    public void process(String msg){
        System.out.println("topicexchange messages 消费者  : " +msg);
    }
}

4.创建controller

package com.paic.controller;

import com.paic.producer.TopicExchangeProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ProjectName: rabbitmqproducer
 * @Package: com.paic.controller
 * @ClassName: TopicExchangeProducer
 * @Author: Administrator
 * @Description: ${description}
 * @Date: 2019/6/23 17:53
 * @Version: 1.0
 */
@RestController
public class TopicExchangeController {

    @Autowired
    private TopicExchangeProducer topicExchangeProducer;

    @RequestMapping("/topicexchange")
    public String topicExchange(){
        topicExchangeProducer.send();
        return "ok";
    }
}

5.按上面方法进行测试
在这里插入图片描述
结果发现队列topic.messages为模糊匹配被消费了两次

4.SpringBoot整合的RabbitMq(Fanout Exchange模式)

1.老套路先来个配置类

package com.paic.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.config
 * @ClassName: FanoutConfig
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Configuration
public class FanoutConfig {
    @Bean
    public Queue AMessage() {
        return new Queue("fanout.A");
    }

    @Bean
    public Queue BMessage() {
        return new Queue("fanout.B");
    }

    @Bean
    public Queue CMessage() {
        return new Queue("fanout.C");
    }

    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange");
    }

    @Bean
    Binding bindingExchangeA(Queue AMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(AMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(BMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(CMessage).to(fanoutExchange);
    }

}

2.接下来是生产者

package com.paic.producer;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.producer
 * @ClassName: FanoutProducer
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Component
public class FanoutProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void send(){
    //论证广播模式和routingkey参数无关
        rabbitTemplate.convertAndSend("fanoutExchange","abcd.ee","--------------");
        rabbitTemplate.convertAndSend("fanoutExchange","abcd.aa","==============");
        rabbitTemplate.convertAndSend("fanoutExchange","***************");
    }
}

3.再创建3个消费者

package com.paic.consumer;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.consumer
 * @ClassName: FanoutCustomerA
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * Fanout Exchange 消费者
 */
@Component
@RabbitListener(queues = "fanout.A")
public class FanoutCustomerA {

    @RabbitHandler
    public void process(String msg){
        System.out.println("FanoutReceiverA  : " + msg);
    }
}

@Component
@RabbitListener(queues = "fanout.B")
public class FanoutCustomerB {

    @RabbitHandler
    public void process(String msg){
        System.out.println("FanoutReceiverB  : " + msg);
    }
}

@Component
@RabbitListener(queues = "fanout.C")
public class FanoutCustomerC {

    @RabbitHandler
    public void process(String msg){
        System.out.println("FanoutReceiverC  : " + msg);
    }
}

4.最后是controller

package com.paic.controller;

import com.paic.producer.FanoutProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.controller
 * @ClassName: FanoutExchangeController
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@RestController
public class FanoutExchangeController {

    @Autowired
    private FanoutProducer fanoutProducer;

    @RequestMapping("/fanoutsend")
    public String fanoutSend(){
        fanoutProducer.send();
        return "ok";
    }
}

5.测试结果
在这里插入图片描述

5.RabbitMq的回调函数使用

1.配置类

package com.paic.config;

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.config
 * @ClassName: CallBackConfig
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Configuration
public class CallBackConfig {
    final static String CALLBACK = "callback";

    @Bean
    public Queue callBackQueue() {
        return new Queue(CALLBACK);
    }

    @Autowired
    private ConnectionFactory connectionFactory;

    @Bean
    /** 因为要设置回调类,所以应是prototype类型,如果是singleton类型,则回调类为最后一次设置 */
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplatenew() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        return template;
    }

}

2.生产者

package com.paic.producer;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.producer
 * @ClassName: CallBackProducer
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Component
public class CallBackProducer implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void send() {
        rabbitTemplate.setReturnCallback(this);
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.convertAndSend("callback", "回调函数:生产者发出的消息");
    }

    /**
     * 发送后的回调函数
     *
     * @param correlationData
     * @param b
     * @param s
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        System.out.println("回调函数:" + "b=" + b);
    }

    /**
     * 消息发送失败的回调函数(未测试)
     *
     * @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("发送消息失败");
    }
}

3.消费者

package com.paic.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.consumer
 * @ClassName: CallBackCustomer
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@Component
public class CallBackCustomer {
    @RabbitListener(queues = "callback")
        @RabbitHandler
        public void process(String msg){
            System.out.println("回调函数-消费者:"+msg);
        }
    }


4.controller

package com.paic.controller;

import com.paic.producer.CallBackProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ProjectName: rabbitmq
 * @Package: com.paic.controller
 * @ClassName: CallBackController
 * @Author: Administrator
 * @Description: ${description}
 * @Version: 1.0
 */
@RestController
public class CallBackController {
    @Autowired
    private CallBackProducer callBackProducer;

    @RequestMapping("/callback")
    public void send(){
        callBackProducer.send();
    }
}

5.测试结果
在这里插入图片描述
更多关于rabbitmq的知识https://www.liangzl.com/get-article-detail-21195.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值