RabbitMQ学习

前言

    通过在慕课网学习,进行RabbitMQ的了解、安装、和SpringBoot的整合使用。

一、RabbitMQ简介及AMQP协议

1.1 初识RabbitMQ

初识RabbitMQ

1.目前大多数互联网都在使用RabbitMQ

2.RabbitMQ底层采用Erlang语言进行编写(需要Erlang环境,Erlang语言在交换机领域非常受欢迎的,复制数据低延迟)

3.开源、性能优秀,稳定

4.与SpringAMQP完美的整合、API丰富

5.集群模式丰富,表达式配置,HA模式,镜像队列模型(主从模式、远程模式、双活模式、镜像队列模式:保证数据的不丢失,完善的架构:HAproxy实现负载均衡,上层再加keepalive保证高可用)

6.保证数据不丢失的前提下做到高可靠性、可用性

7.AMQP(Advanced Message Queuing Protocol,高级消息队列协议)

AMQP协议模型

Publisher application:生产者应用

Consumer application:消费者应用

Server:MQ服务,即RabbitMQ

Virtual host:虚拟主机

Exchange:交换机,和消息队列之间有绑定关系(Route Key)

Message Queue:消息队列


二、RabbitMQ安装及使用

主要安装过程

2.2 下载

wget https://www.rabbitmq.com/releases/erlang/erlang-18.3-1.el7.centos.x86_64.rpm

wget http://repo.iotti.biz/CentOS/7/x86_64/socat-1.7.3.2-5.el7.lux.x86_64.rpm

wget https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.5/rabbitmq-server-3.6.5-1.suse.noarch.rpm

如果出现下面的情况,是需要在wget参数中增加--no-check-certificate

增加--no-check-certificate

最后下载了下面的三个文件

wget下载的三个文件

安装顺序为:1.erlang,2.socat,3.rabbitmq

因为rabbitmq是在erlang环境的运行的,并且需要socat秘钥,最后安装rabbitmq

使用rpm -ivh rpm包名称 安装rpm包,如:

rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm

2.3 配置

配置/etc/hostname和/etc/hosts,主机名称和主机关系


配置/etc/hostname和/etc/hosts

配置/usr/lib/rabbitmq/lib/rabbitmq_server-3.6.5/ebin/rabbit.app

tcp_listeners就是启动后应用程序访问的端口,loopback_users就是一会我们要用到的用户,改成如图所示即可

rabbit配置

输入命令:rabbitmq,按两下Tab键,会发现有三个选项rabbitmqctl rabbitmq-plugins rabbitmq-server

rabbitmqctl是控制rabbitmq的,如集合、队列等等

rabbitmq-plugins是管理插件的

rabbitmq-server就是控制服务了

我们这时使用命令:rabbitmq-server start &启动rabbitmq服务

启动rabbitmq服务

completed with 0 plugins,即我们当前没有使用插件

因为我们是使用5672端口启动的,使用命令lsof -i:5672确定服务已启动

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

beam.smp 1812 rabbitmq  52u  IPv6  23637      0t0  TCP *:amqp (LISTEN)

2.4 管理插件

使用命令:rabbitmq-plugins list查看插件列表

使用命令:rabbitmq-plugins enable rabbitmq_management启动控制台

2.5 访问控制台

使用http://ip:15672即可访问控制台,输入账号/密码:guest/guest

控制台样式

控制台可以查看rabbitmq的基本信息及实时情况,也可以进行添加队列、用户等操作。

2.6 

三、RabbitMQ核心概念

3.1 RabbitMQ的整体架构

RabbitMQ的整体架构

3.2 AMQP核心概念

Server:又称Broker,接收客户端的连接,实现AMQP实体服务。

Connection:连接,应用程序与Broker的网络连接。

Channel:网络信道,几乎所有的操作都在Channel中进行,Channel是进行消息读写的通道。客户端可建立多个Channel,每个Cha代表一个会话任务。

Message:消息,服务器和应用程序之间传送的数据,有Properties和Body组成。Properties可以对信息进行修饰,比如消息的优先级、延迟等高级特性,也可以是自定义的信息;Body就是消息体内容。

Virtual Host:虚拟地址,用于进行逻辑隔离,最上层的消息路由。一个Virtual Host里面可以有若干个Exchange和Queue,同一个Virtual Host里面不能有相同名称的Exchange和Queue。个人理解认为Virtual Host可以等比为MySQL的数据库。

Exchange:交换机,接受消息,根据路由键转发消息到绑定的队列。

Binding:绑定,Exchange和Queue之间的虚拟连接,Binding中可以包含Routing Key。

Routing Key:一个路由规则,虚拟机可用它来确定如何路由消息。

Queue:也成为Message Queue,消息队列,保存消息并将它们转发给消费者。

3.3 RabbitMQ消息是如何流转的

RabbitMQ消息是如何流转的

生产者应用投递一个Message(需要指定Virtual Host、Exchange、Routing Key),到达Virtual Host(图中没有画出),然后到达Exchange,根据指定的Routing Key确定到达哪个Message Queue,最后由监听了该Message Queue的消费者应用获取。

四、与SpringBoot2.x整合-急速入门

4.1 SpringBoot于RabbitMQ集成

引入依赖

<dependency>

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

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

</dependency>

配置application.properties

spring.rabbitmq.addresses=192.168.47.135:5672

spring.rabbitmq.username=guest

spring.rabbitmq.password=guest

#默认的虚拟主机,也可以自己配置

spring.rabbitmq.virtual-host=/

#连接超时时间,单位毫秒

spring.rabbitmq.connection-timeout=15000

4.2 编写发送消息服务代码

消息实体类

//一定要实现Serializable,并有serialVersionUID,因为一定是要通过网络传输的

public class Order implements Serializable {

    private static final long serialVersionUID = 1550918097811388561L;

    private String id;

    private String name;

    private String messageId;  //存储消息发送的唯一标识,id对应的messageId

    get、set、constructor...

}

订单发送服务

@Component

public class OrderSender {

    @Autowired

    private RabbitTemplate rabbitTemplate;

    public void sendOrder(Order order) throws Exception {

        CorrelationData correlationData = new CorrelationData();

        correlationData.setId(order.getMessageId());

        rabbitTemplate.convertAndSend(

                "order-exchange",  //exchange

                "order.abcd",          //routingKey

                order,                     //消息体内容

                correlationData      //correlationData,用于指定消息的唯一ID

        );

    }

}

4.3 配置RabbitMQ

创建exchange

创建exchange

打开mq管理界面,按照上面的示意,填写Name(order-exchange),选择Type(topic),选择Durability(Durable)将消息持久化到硬盘上,最后点击Add exchange完成Exchange的添加。添加后就是图中的order-exchange。

常用的Exchange Type有三种:fanout、direct、topic

fanout:把所有发送到该Exchange的消息投递到所有与它绑定的队列中。

direct:把消息投递到那些binding key与routing key完全匹配的队列中。

 topic:将消息路由到binding key与routing key模式匹配的队列中。

添加Queue

添加queue

打开mq管理界面,按照上面的示意,填写Name(order-queue),选择Durability(Durable)将消息持久化到硬盘上,最后点击Add queue完成Queue的添加。添加后就是图中的order-queue。

在Exchange侧添加Routing Key进行Binding

在Exchange侧添加Routing Key进行Binding

在Exchange界面点击order-exchange即可进入上图的界面,填写To queue为order-queue(即刚才创建的队列名称),Routing key为order.#

在Routing Key填写时注意:

# 表示后面可以有多个 . 的内容进行路由,即order.a可以根据该Routing Key路由到对应的Queue,order.a.b.c也可以,order01.a是不可以的。

* 表示只能有一个 . 的内容进行路由,即order.a可以根据该Routing Key路由到对应的Queue,order.a.b.c不可以,order01.a是不可以的。

下图即为Binding成功的样子

Binding成功

从Queue侧也可以看到

Queue侧查看Binding成功

4.4 编写测试代码进行测试

编写代码

@Autowired

private OrderSender orderSender;

@Test

public void testSendOrder01() throws Exception{

Order order = new Order("201907280000001", "测试订单1", System.currentTimeMillis() + "$" + UUID.randomUUID());

orderSender.sendOrder(order);

}

查看结果

在RabbitMQ控制台确认消息已发送到指定队列

点击order-queue进入队列详情

在RabbitMQ控制台查看已经被序列化为Base64的消息

五、保证100%的消息可靠性投递方案落地实现

5.1 消息可靠性投递方案

消息可靠性投递方案(一)

1.Sender将业务消息写入BIZ DB,并将关联的消息记录写入MSG BD,status:0表示投递中

2.Sender使用异步的方式向MQ Broker投递消息

3.Confirm Listener接收MQ Broker异步通知的投递成功通知

4.Confirm Listener将MSG DB的修改status:1,表示投递成功

5.分布式定时任务从MSG DB获取status:0的数据,重新交给Sender向MQ Broker投递消息

6.分布式定时任务发现重试次数大于3时,将MSG DB的数据修改status:2,表示投递失败

第二步和第三步可能因为网络原因或MQ Broker原因投递失败,此时就需要分布式定时任务获取status:0的数据进行处理

第三步失败时,MQ Broker其实是已经接收到消息了,如果再次投递就会出现重复数据,此时就需要消费端做幂等处理,也就是无论处理几次结果都是一样的

5.2 实现

表结构







©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容