Spring Boot - AMQP 消息中间件
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 消息中间件的更多相关文章
- spring boot / cloud (九) 使用rabbitmq消息中间件
spring boot / cloud (九) 使用rabbitmq消息中间件 前言 rabbitmq介绍: RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.它可以用于大型软件系统 ...
- Spring Boot 入门之消息中间件篇(五)
原文地址:Spring Boot 入门之消息中间件篇(五) 博客地址:http://www.extlight.com 一.前言 在消息中间件中有 2 个重要的概念:消息代理和目的地.当消息发送者发送消 ...
- Spring Boot 入门之消息中间件篇(转发)
一.前言 在消息中间件中有 2 个重要的概念:消息代理和目的地.当消息发送者发送消息后,消息就被消息代理接管,消息代理保证消息传递到指定目的地. 我们常用的消息代理有 JMS 和 AMQP 规范.对应 ...
- spring boot整合activemq消息中间件
spring boot整合activemq消息中间件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi ...
- Spring Boot 2.0 教程 | 快速集成整合消息中间件 Kafka
欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site ...
- Spring Boot 2.0 快速集成整合消息中间件 Kafka
欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site ...
- spring boot实战(第十二篇)整合RabbitMQ
前言 最近几篇文章将围绕消息中间件RabbitMQ展开,对于RabbitMQ基本概念这里不阐述,主要讲解RabbitMQ的基本用法.Java客户端API介绍.spring Boot与RabbitMQ整 ...
- spring boot / cloud (十七) 快速搭建注册中心和配置中心
spring boot / cloud (十七) 快速搭建注册中心和配置中心 本文将使用spring cloud的eureka和config server来搭建. 然后搭建的模式,有很多种,本文主要聊 ...
- Spring Boot消息队列应用实践
消息队列是大型复杂系统解耦利器.本文根据应用广泛的消息队列RabbitMQ,介绍Spring Boot应用程序中队列中间件的开发和应用. 一.RabbitMQ基础 1.RabbitMQ简介 Rabbi ...
随机推荐
- for each ;for in;for of 三者的区别
for each: for each 方法没办法用break语句跳出循环并且无法用return语句从函数体 内返回 for in: 1.index 值 会是字符串(String)类型 2.循环不仅会遍 ...
- SqlServer 游标逐行更新数据,根据上一行的数据来更新当前行
工作中用到的记录一下,游标的详细定义及说明请百度 --游标格式化数据 DECLARE cursor_jxsmb CURSOR FOR --定义一个游标 SELECT F0 FROM dbo.JXSMB ...
- IIs实验,中间件漏洞
实验一.IIS实验 1.修改端口 开始→管理工具→Internet 信息服务(IIS)管理器,属性,将端口改为 8080 如图: 2. IP 地址绑定 前面步骤同第一题一样,将 Ip 改为本 ...
- sqlite当天时间的23:59:59
select strftime('%Y-%m-%d %H:%M:%S','now','+1 day','localtime','start of day','-1 seconds')
- collections&time&random模块
一.collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdic ...
- eclipse启动tomcat错误解决
clipse启动tomcat报出下面的错误提示: 控制台: 九月 06, 2018 9:01:31 下午 org.apache.tomcat.util.digester.SetPropertiesRu ...
- 测试那些事儿-软测必备的linux知识(五)
1.进程管理 1.1进程概述 在Linux中,每个执行的程序都称为一个进程,每个进程都分配一个ID号 每个进程,都会对应一个父进程,这个父进程可以复制多个子进程, 每个进程可能以两种方式存在,前台与后 ...
- 20155219付颖卓《网络对抗》MSF基础应用实验
实验后回答问题 1.用自己的话解释什么是exploit,payload,encode. exploit就是进行攻击的那一步 payload是在目标主机上创建会话连接的 encode是对payload进 ...
- APP测试常用工具以及框架
APP测试常用工具以及框架 1)纯白盒方式的测试,Monkey.一般是开发用的比较多,动手能力强的同学可以自己去尝试下! 2)偏白盒的robotium,这家伙号称是黑盒,但是本人不太认同- 因为使用r ...
- 异常详细信息: System.BadImageFormatException: 未能加载文件或程序集“Maticsoft.Common”或它的某一个依赖项。试图加载格式不正确的程序。
异常详细信息: System.BadImageFormatException: 未能加载文件或程序集“Maticsoft.Common”或它的某一个依赖项.试图加载格式不正确的程序. 解决方法: 点击 ...