1.什么是RabbitMQ

1.1 MQ(Message Queue)消息队列

  • 消息队列中间件,是分布式系统中的重要组件
  • 主要解决,异步处理,应用解耦,流量削峰等问题
  • 从而实现高性能,高可用,可伸缩和最终一致性的架构
  • 使用较多的消息队列产品:RabbitMQ,RocketMQ,ActiveMQ,ZeroMQ,Kafka等

1.1.1 异步处理

  • 用户注册后,需要发送验证邮箱和手机验证码;
  • 将注册信息写入数据库,发送验证邮件,发送手机,三个步骤全部完成后,返回给客户端

一文带你了解RabbitMQ基础知识_RabbitMQ

1.1.2 应用解耦

  • 场景:订单系统需要通知库存系统
  • 如果库存系统异常,则订单调用库存失败,导致下单失败
  • 原因:订单系统和库存系统耦合度太高

一文带你了解RabbitMQ基础知识_订单系统_02

  • 订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户,下单成功;
  • 库存系统:订阅下单的消息,获取下单信息,库存系统根据下单信息,再进行库存操作;
  • 假如:下单的时候,库存系统不能正常运行,也不会影响下单,因为下单后,订单系统写入消息列就不再关心其他的后续操作了,实现了订单系统和库存系统的应用解耦;
  • 所以说,消息队列是典型的:生产者消费者模型
  • 生产者不断的向消息队列中生产消息,消费者不断的从队列中获取消息
  • 因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的入侵,这样就

实现了生产者和消费者的解耦

1.1.3 流量削峰

  • 抢购,秒杀等业务,针对高并发的场景
  • 因为流量过大,暴增会导致应用挂掉,为解决这个问题,在前端加入消息队列

一文带你了解RabbitMQ基础知识_后端_03

  • 用户的请求,服务器接收后,首先写入消息队列,如果超过队列的长度,就抛弃,甩一个秒杀结束的页面!
  • 秒杀成功的就是进入队列的用户;

1.2 背景知识介绍

1.2.1 AMQP高级消息队列协议

  • 即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议
  • 协议:数据在传输的过程中必须要遵守的规则
  • 基于此协议的客户端可以与消息中间件传递消息
  • 并不受产品、开发语言等条件的限制

1.2.2 JMS

  • Java Message Server,Java消息服务应用程序接口,一种规范,和JDBC担任的角色类似
  • 是一个Java平台中关于面向消息中间件的API,用于在两个应用程序之间,或分布式系统中发送消

息,进行异步通信

1.2.3 二者的联系

  • JMS是定义了统一接口,统一消息操作;AMQP通过协议统一数据交互格式
  • JMS必须是java语言;AMQP只是协议,与语言无关

1.2.4 Erlang语言

  • Erlang(['ə:læŋ])是一种通用的面向并发的编程语言,它由瑞典电信设备制造商爱立信所辖的CS-Lab开发,目的是创造一种可以应对大规模并发活动的编程语言和运行环境
  • 最初是由爱立信专门为通信应用设计的,比如控制交换机或者变换协议等,因此非常适合构建分布式,实时软并行计算系统
  • Erlang运行时环境是一个虚拟机,有点像Java的虚拟机,这样代码一经编译,同样可以随处运行

1.3 为什么选择Rabbit MQ

  • Erlang开发,AMQP的最佳搭档,安装部署简单,上手门槛低
  • 企业级消息队列,经过大量实践考验的高可靠,大量成功的应用案例,例如阿里、网易等一线大厂都有使用
  • 有强大的WEB管理页面
  • 强大的社区支持,为技术进步提供动力
  • 支持消息持久化、支持消息确认机制、灵活的任务分发机制等,支持功能非常丰富
  • 集群扩展很容易,并且可以通过增加节点实现成倍的性能提升
  • 如果你希望使用一个可靠性高、功能强大、易于管理的消息队列系统那么就选择
  • Rabbit MQ,如果你想用一个性能高,但偶尔丢点数据不是很在乎可以使用k af ka或者zer oM Q
  • kafka和zeroMQ的性能爆表,绝对可以压RabbitMQ一头!

1.4 Rabbit MQ各组件功能

一文带你了解RabbitMQ基础知识_消息队列_04

  • Broker :消息队列服务器实体
  • VirtualHost :虚拟主机
  • 标识一批交换机、消息队列和相关对象,形成的整体
  • 虚拟主机是共享相同的身份认证和加密环境的独立服务器域
  • 每个vhost本质上就是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器、绑定和权限机制
  • vhost是AMQP概念的基础,RabbitMQ默认的vhost是 /,必须在链接时指定
  • Exchange:交换器(路由)
  • 用来接收生产者发送的消息并将这些消息路由给服务器中的队列
  • Queue:消息队列
  • 用来保存消息直到发送给消费者。
  • 它是消息的容器,也是消息的终点。
  • 一个消息可投入一个或多个队列。
  • 消息一直在队列里面,等待消费者连接到这个队列将其取走。
  • Banding:绑定,用于消息队列和交换机之间的关联。
  • Channel:通道(信道)
  • 多路复用连接中的一条独立的双向数据流通道。
  • 信道是建立在真实的TCP连接内的 虚拟链接
  • AMQP命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,都是通过信道完成的
  • 对于操作系统来说,建立和销毁TCP连接都是非常昂贵的开销,所以引入了信道的概念,用来复用TCP连接。
  • Connection :网络连接,比如一个TCP连接。
  • Publisher :消息的生产者,也是一个向交换器发布消息的客户端应用程序。
  • Consumer :消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。
  • Message:消息
  • 消息是不具名的,它是由消息头和消息体组成。
  • 消息体是不透明的,而消息头则是由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(优先级)、delivery-m ode(消息可能需要持久性存储[消息的路由模式])等。

2.怎么用Rabbit MQ

想要安装RabbitMQ,必须先安装erlang语言环境,类似安装tom cat,必须先安装JDK 查看匹配的版本:​​www.rabbitm​​ q.com /which-erlang.htm l

一文带你了解RabbitMQ基础知识_RabbitMQ_05

2.1 Rabbit MQ安装启动

erlang下载:​​dl.bintray.com/rabbitmq-er…​

socat下载:​​repo.iotti.biz/CentOS/7/x8…​

RabbitMQ下载:​​www.rabbitmq.com/install-rpm…​

2.1.1 安装

rpm -ivh erlang-21.3.8.16-1.el7.x86_64.rpm

rpm -ivh socat-1.7.3.2-5.el7.lux.x86_64.rpm

rpm -ivh rabbitmq-server-3.8.6-1.el7.noarch.rpm

2.1.2 启动后台管理插件

rabbitmq-plugins enable rabbitmq_management

2.1.3 启动Rabbit MQ

systemctl start rabbitmq-server.service

systemctl status rabbitmq-server.service

systemctl restart rabbitmq-server.service

systemctl stop rabbitmq-server.service

2.1.4 查看进程

ps -ef | grep rabbitmq

2.1.5 测试

  1. 关闭防火墙:systemctl stop firewalld
  2. 浏览器输入:​​http://ip:15672​
  • rabbitmqctl set_permissions -p "/" laosun ".*"".*" ".*"
  • ​rabbitmqctl list_users ​
  • rabbitmqctl change_password admin 123456
    1. 查看当前用户和角色

管理界面介绍

一文带你了解RabbitMQ基础知识_后端_06

  • overview:概览
  • connections:查看链接情况
  • channels:信道(通道)情况
  • Exchanges:交换机(路由)情况,默认4类7个
  • Queues:消息队列情况
  • Admin:管理员列表
  • 端口:
  • 5672:RabbitMQ提供给编程语言客户端链接的端口
  • 15672:RabbitMQ管理界面的端口
  • 25672:RabbitMQ集群的端口

2.2 Rabbit MQ快速入门

2.2.1 依赖

<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.7.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
</dependencies>

2.2.2 日志依赖log4j

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target=System.out

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %m%n

log4j.appender.file=org.apache.log4j.FileAppender

log4j.appender.file.File=rebbitmq.log

log4j.appender.file.layout=org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %m%n

log4j.rootLogger=debug, stdout,file

2.2.3、创建连接

package util;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**

* @Description: 专门与RabbitMQ获得连接 */

public class ConnectionUtil {

public static Connection getConnection() throws Exception{

//1.创建连接工厂

ConnectionFactory factory = new ConnectionFactory(); //2.在工厂对象中设置MQ的连接信息(ip,port,vhost,username,password) factory.setHost("192.168.204.141");

factory.setPort(5672);
factory.setVirtualHost("/lagou"); factory.setUsername("laosun"); factory.setPassword("123123"); //3.通过工厂获得与MQ的连接

Connection connection = factory.newConnection(); return connection;

}

public static void main(String[] args) throws Exception{

Connection connection = getConnection();

System.out.println("connection = " + connection);

connection.close();;

} }