Message Broker是一种消息验证、传输、路由的架构模式,其设计目标主要应用于下面这些场景:

  • 消息路由到一个或多个目的地
  • 消息转化为其他的表现方式
  • 执行消息的聚集、消息的分解,并将结果发送到他们的目的地,然后重新组合相应返回给消息用户
  • 调用Web服务来检索数据
  • 响应事件或错误
  • 使用发布-订阅模式来提供内容或基于主题的消息路由

AMQP 是 Advanced Message Queuing Protocol 的简称,它是一个面向消息中间件的开放式标准应用层协议。AMQP定义了这些特性:

  • 消息方向
  • 消息队列
  • 消息路由(包括:点到点和发布-订阅模式)
  • 可靠性
  • 安全性

RabbitMQ 是以 AMQP 协议实现的一种中间件产品,也称为面向消息的中间件,它可以支持多种操作系统,多种编程语言,几乎可以覆盖所有主流的企业级技术平台。下面介绍 RabbitMQ 的基本概念:

  • Broker:可以理解为消息队列服务器的实体,是一个中间件应用,负责接收消息生产者的消息,然后将消息发送至消息接收者或者其他的 Broker
  • Exchange:消息交换机,是消息第一个到达的地方,消息通过他指定的路由规则分发到不同的消息队列中去,有如下几种类型:
    • Direct:完全按照 key 进行投递,比如,绑定时设置了 Routing Key 为 abc,那么客户端提交消息,只有设置了 Key 为 abc 的才会被投递到队列
    • Topic:对于 Key 进行模式匹配后进行投递,可以使用符号 # 匹配一个或多个词,符号 * 匹配正好一个词。比如, abc.# 可以匹配 abc.def.ghi ,而 abc.* 只能匹配 abc.def
    • Fanout:不需要任何 Key,采取广播的模式,一个消息进来时,投递到与该交换机绑定的所以队列
  • Queue:消息队列,消息通过发送和路由之后最终到达的地方,到达 Queue 的消息即进入逻辑上等待消费的状态。每个消息都会被发送到一个或多个队列。
  • Binding:绑定,将 Exchange 和 Queue 按照路由规则绑定起来
  • Routing Key:路由关键字,Exchange 根据该关键字进行消息投递
  • Virtual Host:虚拟主机,他是对 Broker 的虚拟划分,将消费者、生产者和依赖的 AMQP 相关结构进行隔离,一般情况都是为了安全考虑。
  • Connection:连接,代表生产者、消费者、Broker 之间进行通信的物理网络
  • Channel:消息通道,用于连接生产者和消费者的逻辑结构,在客户端的每个连接里,可以建立多个 Channel,每个 Channel 代表一个会话任务,通过 Channel 可以隔离同一个连接的不同交互内容。
  • Producer:消息生产者,制造消息并发送消息的程序
  • Consumer:消息消费者,接收消息并处理消息的程序

 
 

快速入门

我们通过在 Spring Boot 应用中整合 RabbitMQ ,实现一个简单的发送、接收消息的示例:

  • 创建项目

    创建一个 Spring Boot 项目,命名为 spring-boot-rabbitmq,并增加 spring-boot-starter-amqp 依赖,pom.xml 文件内容如下:

    <?xmlversion="1.0"encoding="UTF-8"?>

    <projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

     
     

    <groupId>org.lixue.bus</groupId>

    <artifactId>spring-boot-rabbitmq</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <packaging>jar</packaging>

     
     

    <name>spring-boot-rabbitmq</name>

     
     

    <parent>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-parent</artifactId>

    <version>1.5.12.RELEASE</version>

    <relativePath/><!--lookupparentfromrepository-->

    </parent>

     
     

    <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <java.version>1.8</java.version>

    </properties>

     
     

    <dependencies>

    <dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-amqp</artifactId>

    </dependency>

     
     

    <dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-test</artifactId>

    <scope>test</scope>

    </dependency>

    </dependencies>

     
     

    <build>

    <plugins>

    <plugin>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-maven-plugin</artifactId>

    </plugin>

    </plugins>

    </build>

    </project>

     
     

  • 创建配置

    在 src/main/resources 目录中创建 application.yml 配置文件,并增加 RabbitMQ 相关配置,内容如下:

    #配置应用名称

    spring:

    application:

    name:rabbitmq-bus

    #配置RabbitMQ信息

    rabbitmq:

    #配置连接信息

    addresses:192.168.2.215:5672

    username:lixue

    password:liyong

    virtual-host:/

    #开启发送确认模式

    publisher-confirms:true

     
     

  • 消息生产者

    创建消息生产者 Sender 类,通过注入 AmqpTemplate 接口的实例(org.springframework.amqp.rabbit.core.RabbitTemplate)来实现消息的发送,AmqpTemplate 接口定义了一套针对 AMQP 协议的基础操作,Spring Boot 会根据配置来注入其具体实现。

    package org.lixue.bus;

     
     

    import org.springframework.amqp.core.AmqpTemplate;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Component;

     
     

    import java.util.Date;

     
     

    @Component

    public class Sender{

    @Autowired

    private AmqpTemplate amqpTemplate;

     
     

    public void send(){

    String context="Hello"+new Date();

    //将消息发送到路由Key=send的队列

    amqpTemplate.convertAndSend("send",context);

    }

    }

     
     

  • 消息消费者

    创建消息消费者 Receiver 类,通过注入 AmqpTemplate 接口的实例(org.springframework.amqp.rabbit.core.RabbitTemplate)来实现消息的接收处理,也可以使用 @RabbitListener 和 @RabbitHandler 注解 来指定消息接收的队列和消息处理方法,使用注解处理消息如下:

    package org.lixue.bus;

     
     

    import org.springframework.amqp.rabbit.annotation.RabbitHandler;

    import org.springframework.amqp.rabbit.annotation.RabbitListener;

    import org.springframework.stereotype.Component;

     
     

    @Component

    @RabbitListener(queues="send")

    public class Receiver{

     
     

    @RabbitHandler

    public void process(String message){

    System.out.println("receive:"+message);

    }

    }

     
     

    如果不使用注解,可以通过 AmqpTemplate 接口的实例来获取队列的消息,代码如下:

    package org.lixue.bus;

     
     

    import org.springframework.amqp.core.AmqpTemplate;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Component;

     
     

    @Component

    public class Receiver{

    @Autowired

    private AmqpTemplate amqpTemplate;

     
     

    public void receive(){

    String val=(String)amqpTemplate.receiveAndConvert("send");

    if(val!=null){

    System.out.println("receive:"+message);

    }

    }

    }

     
     

  • 创建配置类

    创建 RabbitMQ 的配置类 RabbitMQConfig,用来配置队列、交换器、路由等高级信息,代码如下:

    package org.lixue.bus;

     
     

    import org.springframework.amqp.core.*;

    import org.springframework.context.annotation.Bean;

    import org.springframework.context.annotation.Configuration;

     
     

    @Configuration

    public class RabbitMQConfig{

     
     

    /**

    *配置队列相关

    */

    @Bean

    public Queue newQueue(){

    return new Queue("send");

    }

     
     

    @Bean

    public Queue newQueue2(){

    return new Queue("send2");

    }

     
     

    /**

    *配置交换器相关

    */

    @Bean

    public Exchange newDirectExchange(){

    return new DirectExchange("directExchange",true,true);

    }

     
     

    @Bean

    public Exchange newTopicExchange(){

    return new TopicExchange("topicExchange",true,true);

    }

     
     

    @Bean

    public Exchange newFanoutExchange(){

    return new FanoutExchange("fanoutExchange",true,true);

    }

     
     

    /**

    *配置队列和交换器绑定

    */

    @Bean

    public Binding newDirectBinding(){

    return BindingBuilder.bind(newQueue()).to(newDirectExchange()).with("send").noargs();

    }

     
     

    @Bean

    public Binding newDirectBinding1(){

    return BindingBuilder.bind(newQueue2()).to(newDirectExchange()).with("send2").noargs();

    }

    }

     
     

  • 测试验证

    创建消息提供者的单元测试,在单元测试中执行消息发送方法,并执行单元测试,如果使用注解的方式接收消息,则不需要做额外处理,Spring Boot 启动后会接收消息,如下:

    package org.lixue.bus;

     
     

    import org.junit.Test;

    import org.junit.runner.RunWith;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.boot.test.context.SpringBootTest;

    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

    import org.springframework.test.context.junit4.SpringRunner;

     
     

    import static org.junit.Assert.*;

     
     

    @RunWith(SpringRunner.class)

    @SpringBootTest

    publi cclass SenderTest{

     
     

    @Autowired

    private Sender sender;

     
     

    @Test

    public void send() throws Exception{

    for(inti=0;i<1000000;i++){

    sender.send(i);

    }

    }

    }

    日志输出如下:

    2018-05-04 16:23:39.085 INFO 20176 --- [cTaskExecutor-1] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [192.168.2.215:5672]

    2018-05-04 16:23:39.294 INFO 20176 --- [cTaskExecutor-1] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#232532cf:0/SimpleConnection@7c7f9a81 [delegate=amqp://lixue@192.168.2.215:5672/, localPort= 63144]

    2018-05-04 16:23:39.300 INFO 20176 --- [cTaskExecutor-1] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable or auto-delete Exchange (directExchange) durable:true, auto-delete:true. It will be deleted by the broker if it shuts down, and can be redeclared by closing and reopening the connection.

    2018-05-04 16:23:39.300 INFO 20176 --- [cTaskExecutor-1] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable or auto-delete Exchange (topicExchange) durable:true, auto-delete:true. It will be deleted by the broker if it shuts down, and can be redeclared by closing and reopening the connection.

    2018-05-04 16:23:39.301 INFO 20176 --- [cTaskExecutor-1] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable or auto-delete Exchange (fanoutExchange) durable:true, auto-delete:true. It will be deleted by the broker if it shuts down, and can be redeclared by closing and reopening the connection.

    2018-05-04 16:23:39.476 INFO 20176 --- [ main] org.lixue.bus.SenderTest : Started SenderTest in 4.536 seconds (JVM running for 6.026)

    receive:Hello Fri May 04 16:23:39 CST 2018

    receive:Hello Fri May 04 16:23:39 CST 2018

    receive:Hello Fri May 04 16:23:39 CST 2018

    receive:Hello Fri May 04 16:23:39 CST 2018

     
     

Spring Boot - AMQP 消息中间件的更多相关文章

  1. spring boot / cloud (九) 使用rabbitmq消息中间件

    spring boot / cloud (九) 使用rabbitmq消息中间件 前言 rabbitmq介绍: RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.它可以用于大型软件系统 ...

  2. Spring Boot 入门之消息中间件篇(五)

    原文地址:Spring Boot 入门之消息中间件篇(五) 博客地址:http://www.extlight.com 一.前言 在消息中间件中有 2 个重要的概念:消息代理和目的地.当消息发送者发送消 ...

  3. Spring Boot 入门之消息中间件篇(转发)

    一.前言 在消息中间件中有 2 个重要的概念:消息代理和目的地.当消息发送者发送消息后,消息就被消息代理接管,消息代理保证消息传递到指定目的地. 我们常用的消息代理有 JMS 和 AMQP 规范.对应 ...

  4. spring boot整合activemq消息中间件

    spring boot整合activemq消息中间件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi ...

  5. Spring Boot 2.0 教程 | 快速集成整合消息中间件 Kafka

    欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site ...

  6. Spring Boot 2.0 快速集成整合消息中间件 Kafka

    欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site ...

  7. spring boot实战(第十二篇)整合RabbitMQ

    前言 最近几篇文章将围绕消息中间件RabbitMQ展开,对于RabbitMQ基本概念这里不阐述,主要讲解RabbitMQ的基本用法.Java客户端API介绍.spring Boot与RabbitMQ整 ...

  8. spring boot / cloud (十七) 快速搭建注册中心和配置中心

    spring boot / cloud (十七) 快速搭建注册中心和配置中心 本文将使用spring cloud的eureka和config server来搭建. 然后搭建的模式,有很多种,本文主要聊 ...

  9. Spring Boot消息队列应用实践

    消息队列是大型复杂系统解耦利器.本文根据应用广泛的消息队列RabbitMQ,介绍Spring Boot应用程序中队列中间件的开发和应用. 一.RabbitMQ基础 1.RabbitMQ简介 Rabbi ...

随机推荐

  1. 第十六周翻译-SQL Server复制的阶梯:第1级 - SQL Server复制简介

    SQL Server复制的阶梯:第1级 -  SQL Server复制简介 作者:Sebastian Meine,2012年12月26日 翻译:赖慧芳 译文: 该系列 本文是Stairway系列的一部 ...

  2. SharePoint Framework解决方案管理参考(二)

    博客地址:http://blog.csdn.net/FoxDave 使用外部脚本 在使用现有的JavaScript脚本库时,开发者可以选择将它们包含在web部件代码包中,或者从外部的URL加载.从外部 ...

  3. IntelliJ IDEA 使用教程(2019图文版) -- 从入门到上瘾

    IntelliJ IDEA 使用教程(2019图文版) -- 从入门到上瘾   前言:IntelliJ IDEA 如果说IntelliJ IDEA是一款现代化智能开发工具的话,Eclipse则称得上是 ...

  4. callback回调函数的理解

    callback采用的设计模式是:模板模式,他的设计理念是基于面向对象中的多态的. 我们的程序中走到某个地方他会出现不一样的动作的时候,我们在这儿就使用回调函数.我们利用的就是 多态的原理,我们传递不 ...

  5. top和nvidia-smi无法显示占用GPU的PID问题

    通过nvidia-smi查看显卡使用情况,发现显卡在被占用,但是却没有提示占用显卡的进程id, 这时可以输入 fuser -v /dev/nvidia* 可以查看到, 再利用sudo kill -9 ...

  6. Js/Session和Cookies的区别

    1.cookies数据存放在客户的浏览器上面,session放在服务器上面.2.cookies不安全,别人可以分析浏览器的数据进行cookies的欺骗,考虑到安全性,应该使用cookie3.sessi ...

  7. Spark的mlib中的稠密向量和稀疏向量

    spark mlib中2种局部向量:denseVector(稠密向量)和sparseVector(稀疏向量) denseVector向量的生成方法:Vector.dense() sparseVecto ...

  8. webpack前端开发环境搭建

    要搭建webpack开发环境,首先要安装NodeJS,后面的过程均在NodeJS已经安装的基础上进行. 1. 首先建立一个工程目录,命名为,其目录结构如下: 其中dist目录用于存放生成的文件,src ...

  9. LR-SVM(有待重新整理)

    参考:http://www.zhihu.com/question/26768865 总结: 1)在线学习:SVM不支持在线学习,LR支持 2)不平衡数据:SVM不依赖于数据的分布,所以数据是否平衡影响 ...

  10. 百战程序员——Spring框架

    什么是容器,我们学过了哪些容器,Spring与我们之前学习的容器有哪些异同点? 容器可以管理对象的生命周期.对象与对象之间的依赖关系,您可以使用一个配置文件(通常是XML),在上面定义好对象的名称.如 ...