一、引言
模块之间的耦合度过高,导致一个模块宕机后,全部功能都不能用了,并且同步通讯的成本过高,用户体验差。
RabbitMQ引言 |
---|
二、RabbitMQ介绍
MQ全称为Message Queue,消息队列是应用程序和应用程序之间的通信方法。
RabbitMQ是一个Erlang开发的AMQP(高级消息排队 协议)(英文全称:Advanced Message Queuing Protocol )的开源实现。
2.1 为什么使用MQ
在项目中,可将一些无需即时返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
开发中消息队列通常有如下应用场景:
(1) 异步操作:
任务异步处理将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
(2) 解耦:
应用程序解耦合MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合
(3) 削峰:
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用MQ能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
(4) 可恢复性: ·
系统的一部分组件失效时,不会影响到整个系统。MQ降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
2.2. 消息队列产品
市场上常见的消息队列有如下:
-
ActiveMQ:基于JMS实现, 比较均衡, 不是最快的, 也不是最稳定的.
-
ZeroMQ:基于C语言开发, 目前最好的队列系统.
-
RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好, 数据基本上不会丢失
-
RocketMQ:基于JMS,阿里巴巴产品, 目前已经捐献给apahce
-
Kafka:类似MQ的产品;分布式消息系统,高吞吐量, 目前最快的消息服务器,
2.3. AMQP 和 JMS
MQ是消息通信的模型;实现MQ的大致有两种主流方式:AMQP、JMS。
2.3.1. AMQP
AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。
2.3.2. JMS
JMS即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
2.3.3. AMQP 与 JMS 区别
JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。JMS规定了两种消息模式;而AMQP的消息模式更加丰富.
JMS | AMQP | |
---|---|---|
定义 | Java api | Wire-protocol |
跨语言 | 否 | 是 |
跨平台 | 否 | 是 |
2.4. RabbitMQ
RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。
RabbitMQ官方地址:RabbitMQ: One broker to queue them all | RabbitMQ
RabbitMQ提供了6种模式:Hello Word简单模式,work工作模式,Publish/Subscribe发布与订阅模式,Routing路由模式,Topics主题模式(通配符模式),RPC远程调用模式(dubbo)(远程调用,不太算MQ;不作介绍)
官网对应模式介绍:RabbitMQ Tutorials | RabbitMQ
2.5 相关定义:
-
Broker: 简单来说就是消息队列服务器实体
-
Exchange: 消息交换机,它指定消息按什么规则,路由到哪个队列
-
Queue: 消息队列载体,每个消息都会被投入到一个或多个队列
-
Binding: 绑定,它的作用就是把exchange和queue按照路由规则绑定起来
-
Routing Key: 路由关键字,exchange根据这个关键字进行消息投递
-
VHost: 虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
-
Producer: 消息生产者,就是投递消息的程序
-
Consumer: 消息消费者,就是接受消息的程序
-
Channel: 消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务
由Exchange、Queue、RoutingKey三个才能决定一个从Exchange到Queue的唯一的线路。
三、RabbitMQ安装
version: "3.1"
services:
rabbitmq:
image: daocloud.io/library/rabbitmq:management
restart: always
container_name: rabbitmq
ports:
- 5672:5672
- 15672:15672
volumes:
- ./data:/var/lib/rabbitmq
-
管理端界面访问地址:
http://虚拟机ip:15672
-
用户名 : guest
-
密码 : guest
四、RabbitMQ架构【重点
】
完整架构图
完整架构图 |
---|
五. Spring Boot整合RabbitMQ
5.1. 简介
在Spring项目中,可以使用Spring-Rabbit去操作RabbitMQ GitHub - spring-projects/spring-amqp: Spring AMQP - support for Spring programming model with AMQP, especially but not limited to RabbitMQ尤其是在spring boot项目中只需要引入对应的amqp启动器依赖即可,方便的使用RabbitTemplate发送消息,使用注解接收消息。
一般在开发过程中:
生产者工程:
-
application.yml文件配置RabbitMQ相关信息;
-
在生产者工程中编写配置类,用于创建交换机和队列,并进行绑定
-
注入RabbitTemplate对象,通过RabbitTemplate对象发送消息到交换机
消费者工程:
-
application.yml文件配置RabbitMQ相关信息
-
创建消息处理类,用于接收队列中的消息并进行处理
5.2. 搭建生产者工程
5.2.1. 创建工程
创建生产者工程springboot_rabbitmq_producer
5.2.2. 添加依赖
修改pom.xml文件内容为如下:
<?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.tingyi</groupId>
<artifactId>springboot_rabbitmq_producer</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<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>
</dependency>
</dependencies>
</project>
5.2.3. 启动类
package com.tingyi.rabbitmq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author tingyi
*/
@SpringBootApplication
public class ProducerApplication {
public static void main(String[]args) {
SpringApplication.run(ProducerApplication.class, args);
}
}
5.2.4. 配置RabbitMQ
1)配置文件
创建application.yml,内容如下:
spring:
rabbitmq:
host: 自己的地址
port: 5672
virtual-host: /tingyi
username: test
password: test
5.3. 搭建消费者工程
5.3.1. 创建工程
创建消费者工程springboot_rabbitmq_consumer
5.3.2. 添加依赖
修改pom.xml文件内容为如下:
<?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.tingyi</groupId>
<artifactId>springboot_rabbitmq_consumer</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
</project>
5.3.3. 启动类
package com.tingyi.rabbitmq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author tingyi
*/
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
5.3.4. 配置RabbitMQ
创建application.yml,内容如:
spring:
rabbitmq:
host: 你的地址
port: 5672
virtual-host: /tingyi
username: test
password: test