索引
背景
开局一只狗,介绍是少不了的,那么对于我这种渣渣来说,看源码,ctry+左键,翻得翻得好像搞明白源码的流程了,再回头yy,咦?我清楚的有那一个步骤来着,是干啥来着???就很难受,不得不面对真实的自己,不哔哔了,淦!
一个故事:异步处理
淦之前还得哔哔一个故事:
脑补这个一个场景,我要注册一个网站的会员,按他们的流程是:用户注册后给发一份邮件、给用户发优惠券、发糖、发小板凳。。。一系列操作
如果我是开发者,是不是有这么几个思想:
1:用户注册后,直接调用发邮件、发糖、发小板凳等等一系列操作,统统一下子都执行,执行完成后给用户true。
2:用户注册后,利用多线程的方式,并发执行操作,操作完告诉用户true。
3:用户注册后,把后续任务写入消息队列成功,给用户true,然后程序默默的执行一系列操作或者多线程执行。
相比之下,那绝对是第三种方式体验贼棒啊,响应速度相比第一种和第二种快了N倍,现在这个流量时代,抓不住用户的喜好,就与用户无缘。
一个故事:应用解耦
订单与库存:订单系统处理完之后直接请求库存系统,进行库存商品自减,像是连体婴
方案:订单系统只管下命令,不直接找库存系统了,而是发到消息队列,库存系统去消息队列取任务,双方谁也不紧张。
一个故事:流量削峰
十万个人同时要抢诺亚方舟的船票,可票只有10张,我的系统不可能判断十万次请求,一个个跑订票的业务逻辑。
消息队列:你尽管抢,我消息队列只存100个请求,剩下的9万9千9百请求直接返回抢票失败,也就不进订票的业务,剩下的100个请求再慢慢研究谁是最后10名幸运儿。
例子有些激进,主要理解消息队列和名词。
概述
消息服务中两个重要概念:
1:消息代理:消息发送者发送消息后,由消息代理接管,消息代理保证消息传递到指定目的地。
2:目的地:消息队列主要有两种形式的目的地,队列(点对点)和主题(发布/订阅)
点对点式:
A发送消息到消息代理,B可以从消息代理取出消息,然后消息代理里的消息就没了。当然不止是B可以拿消息,也可以有C、D…如果A拿走了消息,别人就拿不到了。这个拿走就叫消费。大白话,蟹堡王门口N个人排队,但只有一个蟹黄堡,派大星吃掉这个蟹黄堡后,别人就只有饿肚子。
发布/订阅式:
wx公众号,关注了公众号之后,他发任何消息,关注者都会收到
消息代理规范
JMS (Java Message Service):Java提供的消息服务
AMQP(Advanced Message Queuing Protocol):高级消息队列,兼容JMS,RabbitMQ是AMQP的实现。
RabbitMQ简介
RabbitMQ消息队列嘛,它是erlang开发的AMQP的开源实现,用来解决上边说的几种业务场景。这个erlang就很神奇,之前我有个win虚拟机,给装过RabbitMQ,过了好久,找的时候发现找不见了,怀疑有没有装过,后来才发现一个叫erlang的文件夹。。。
核心概念
1.Message:消息,由消息头和消息体组成。消息体不透明,消息头类似http请求头,不过参数不一样,可以这么理解。其中头里边重要的是routing-key(路由键)、priority(相对于其它消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)
2.Publisher:消息的生产者,也是一个向交换器发布消息的客户端应用程序。
3.Exchange:交换器,用来接收生产者发送的消息,并把这些消息路由给服务器中的队列。它有四种类型:direct(默认)、fanout、topic、headers,direct是点对点式的,其它的是发布/订阅式的,策略不一样。交换器根据消息头的路由键来指定消息该去哪。
4.Queue:消息队列,用来保存消息直接发送给消费者。它是消息的容器,一个消息可以投入一个或多个队列。消息一直在队列里,等待消费者过来把它取走。
5.Binding:绑定,消息队列与交换器之间的关联。就是 根据路由键派发消息到哪个消息队列的规则。绑定规则可以是多对多的关系。
6.Connection:网络连接,比如一个TCP连接。
7.Channel:信道,比如TCP建立连接后,不可能有多条,因为太耗费资源了,所以信道就是说,在一个连接里开辟多条通道,信道才是真正发送消息、接收消息。。。用的
8.Consumer:消息的消费者,从消息队列取消息的
9.Virtual Host:虚拟主机,表示一批交换器、消息队列和相关对象。每个虚拟主机相当于mini版RabbitMQ服务器,相互隔离,有自己完整的一套队列、交换器、绑定、权限机制。必须在连接时指定,RabbitMQ默认的vhost是“/”(斜杠)。也可以这么理解,虚拟主机就是多个相互隔离的RabbitMQ服务器。
10.Broker:代理,就是消息队列服务器实体
关系图

RabbitMQ运行机制
消息是如何抵达队列的?
首先,生产者创建出一个消息,发给消息队列服务器,但是首先抵达的是队列服务器里的交换器,交换器根据这个消息的路由键,把它派发到某队列,派发规则就叫绑定,而且可以是多对多的关系(一个交换器可以绑定好多队列,一个队列也可以被多个交换器绑定)。那么核心也就可想而知,就是交换器和绑定规则。
交换器(Exchange)
Exchange分发消息时,根据类型的不同分发策略也有区别。目前共有四种类型:direct、fanout、topic、headers。headers匹配的是消息的header而不是路由键,与direct完全一致,但性能差很多,所以直接看另外三种就可以了。
1.Direct Exchange:典型的点对点通信模型(单播),当路由键与绑定的键一模一样的时候派发给相应队列。举个栗子,比如有三个消息队列,分别是cat、cat.eat、cat.sleep,当路由键是cat的时候,只会给cat这个消息队列发送消息。
2.Fanout Exchange:广播模式,还是那三个队列,不管路由键是啥,这三个队列都会收到发来的消息。这个是发消息最快的,也是发布/订阅模型的参考实现。
3.Topic Exchange:还是那三个队列,队列允许模糊匹配,符号是#和*,#匹配0个或多个单词,*匹配一个单词,比如cat.#、#.cat。完成有选择性的广播通信。
RabbitMQ安装
1.移驾centos7,xshell连上
2.查看镜像,是否有RabbitMQ:
docker images
3.没安装过肯定没有,所以去dockerhub一趟,搜下,并确定要安装的版本,推荐安装tag带manager的,因为带管理界面。然后docker pull,找国内镜像加速站加速
//不加速
docker pull rabbitmq:3.8.9-management-alpine
//加速
docker pull 3laho3y3.mirror.aliyuncs.com/library/rabbitmq:3.8.9-management-alpine
4.再看下镜像:这次肯定有了
docker images
5.然后启动运行镜像,-d代表后台运行,带管理界面的RabbitMQ有两个端口,分别是5672和15672,-p暴露端口,把主机的5672映射到docker容器的5672,15672同理,–name是给起个名字,后边跟上容器id。顺便看一下运行没。看到运行了就可以尝试访问管理界面,默认账号密码都是guest。
docker run -d -p 5672:5672 -p 15672:15672 --name myrabbitmq 5c00f781d2c7

RabbitMQ界面操作(创建交换器、消息队列、 绑定关系)
访问成功后,继续看界面,上边一排6个菜单,点到交换器,人家默认有7个交换器,先不管他,自己新建上边说的那三种类型的交换器,注意Durability选项,意思是持久化,如果是持久化,下次重启RabbitMQ这个交换器还在,不持久化重启后就没这个交换器了。


交换器建好后,点到队列建4个消息队列。

交换器和队列都建好之后,点到交换器搞绑定关系,进入dirct,填写to queue,Routing key(路由键)完成绑定,绑定如下图

进入fanout,绑定如下图,因为是广播,所以路由键可有可无。

进入topic,用#、*匹配,绑定如下图。

RabbitMQ消息测试
接下来进行测试。
Drict测试
先进入dirct,写路由键和信息,publish message

因为是点对点,所以完全匹配的绑定规则才会被队列保存。

本文介绍了RabbitMQ在SpringBoot中的应用,通过异步处理、应用解耦和流量削峰的故事场景阐述其重要性。详细讲解了RabbitMQ的核心概念、运行机制,以及如何在SpringBoot中使用RabbitTemplate发送和接收消息,包括消息序列化为JSON。还涵盖了RabbitMQ的安装、界面操作、AmqpAdmin管理组件的使用,以及消息监听的实现。
最低0.47元/天 解锁文章
1301





