什么是消息队列
消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它。y
简单点说:消息队列是应用程序和应用程序之间的通信方法。当我们将大项目拆分为许多许多小模块时,我们在这些模块中需要通信时,利用传统的做法就是通过网络调用,这种做法在遇到高并发、网络异常的情况下,所带来的情况便是响应时间的变长,及可能带来服务的失败。
这时我们就要使用上消息队列了。我们可将一些无需即时返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
消息队列的好处
解耦
消息队列相当于一个中介,生产方通过j消息队列与消费方交互,消息队列将生产者和消费者的依赖关系分离开,实现了解耦合,消费方无须关心生存方一方的的业务,只需得到相应的通知,然后就会去做对应的事,这样各个模块之间就解耦了。
异步处理
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。当我们去执行一段业务时,我们需要通过网络调用另一段与主线业务无关的业务时,我们可以利用消息队列,将这一段业务交给消息队列去执行,我们只需执行完主线业务然后返回结果即可。
举个例子:当我们需要执行【注册业务】时,我们需要执行【发短信业务】,可【发短信业务】所带来的时间,是非常非常久的,这时,我们便可以将【发短信业务】放在消息队列中,从而不会拖慢【注册业务】的时间。
削峰/限流
让消息不直接到达服务器,先让消息队列保存这些数据,减少同一时刻对服务器的压力。当同一时刻的请求激增时,我们可以将生产者的请求存储在消息队列中,限制消费方消费消息的速度,这样一来,当出现请求高峰期的时候,不至于将服务器压垮,这种我们就叫削峰
举个例子:【订单系统】当高峰期所达到的高并发足以压垮服务器时,我们可以将下单的请求存到消息队列中,限制服务器的请求量。
消息队列的实现方式
JMS
Java消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
JMS在特定的API接口层面和实现行为上进行了统一。
AMQP
高级消息队列协议即Advanced Message Queuing Protocol(AMQP)是面向消息中间件提供的开放的应用层协议。AMQP规范了消息传递方和接收方的行为,以使消息在不同的提供商之间实现互操作性,就像SMTP,HTTP,FTP等协议可以创建交互系统一样。高级消息队列协议关注于各种消息如何以字节流的形式进行传递。因此,使用了符合协议实现的任意应用程序之间可以保持对消息的创建、传递。
简单点说:JMS定义接口来实现,AMQP通过协议实现,AMQP可以通过网络来传递,因此AMQP是跨语言的
消息队列产品
ActiveMQ
ZMQ:
RabbitMQ:
RockerMQ:
Kafka:
RabbitMQ
RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。
RabbitMQ提供了7种模式:简单模式,工作队列模式,发布与订阅模式,路由模式,通配符模式,RPC模式,发布者确认模式。
关于RabbitMQ的下载和安装,官网一步到位,这里就不做说明了
当我们下载安装完RabbitMQ后(RabbitMQ的默认账号是guest 密码 guest 默认端口15672)
访问RabbitMQ的网址,看到以下画面即为成功安装。
RabbitMQ的几个概念
Connection(连接):
基于AMQP协议的网络连接,比如TCP/IP套接字连接。当使用RabbitMQ时便会创建连接,开启信道,连接到RabbitMQ,当消息发送完毕便会关闭信道、关闭连接。
Channel(信道):
RabbitMQ之间使用 TCP 连接,加入每次发布消息都要连接TCP,这不仅会造成连接资源严重浪费,RabbitMQ 引入了信道的概念,所有需要发布消息的线程都包装成一条信道在 TCP 中传输,理论上 一条 TCP 连接支持无限多个信道。
Exchanges(交换机):
在Rabbit的几种模式中,从发布订阅模式开始便引入了交换机这一概念,利用交换机,将消息存放在交换机中,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收消息,做到了一条消息多个共享。
Queues(队列):
用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
virtual_host(域)
域是rabbitmq分配权限的最小细粒度。比如我们可以为一个用户分配一个可以访问哪个域。所以可以多个user共同使用一个virtual host,不同的命名空间之间的资源是不能访问的。域是一个权限的标记,标记用户访问的权限
快速入门
依赖
消费者和生产者依赖相同
配置文件
在RabbitMQ的官方文档中,我们可以看到我们需要发送方和接收方。为了方便,这里统一使用SpringBoot整合RabbitMQ,SpringBoot为我们解决了繁琐的创建过程,其他方式差不多一样,有兴趣可以到官方文档中查看,这里就不一一演示。这里讲几个典型的,其他可参考官方文档。
我们将调用消息发布者(发送方)Send和消息使用者(接收方)Recv。发布者将连接到RabbitMQ,发送一条消息,然后退出。在发送。java,我们需要导入一些类
简单模式
一个生产者、一个消费者,依靠队列交换消息,队列相当于一个中转站
- P:生产者: 发送消息到队列
- C:消费者: 消费队列中的消息
- Queue:消息队列,接收消息、缓存消息。
生产者
模拟一个消息的发送
配置类
启动看效果
我们可以看到在RabbitMQ的页面上生成了信道和队列
消费者
监听队列
到这里简单模式的的入门就到处为止了。
简单模式是里面典型的一种模式,指不加入交换机,单点对单点的这种形式,这种模式的缺点就是一个消息就只能由一个消费,,不能做到多个消费者共用同一个消息,这种模式还有工作队列模式,工作队列只不过在简单模式的基础上有多个消费者而已,因此就不做演示。
发布与订阅模式
P:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)
C:消费者, 消费队列中的消息。
Queue:消息队列,接收消息、缓存消息。
X:- Exchange:交换机,。一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如把消息递交给某个特别队列、递交给所有队列、或是将消息丢弃。 到底如何操作,取决于Exchange的类型。Exchange有常见以下3种类型:
- Fanout:广播,将消息交给所有绑定到交换机的队列
- Direct:定向,把消息交给符合指定routing key 的队列
- Topic:通配符,把消息交给符合的队列,模糊匹配。
绑定交换机
第二个参数为路由模式的参数,如无,为空即可
配置类
·配置交换机
消费者(编写两个消费者)
绑定队列和交换机
启动后在RabbitMQ中生成了新的交换机和新的信道
启动测试
路由模式
路由模式即多了一个路由的key,只有拥有指定路由key的消费者才可以访问
生产者
配置类
消费者
在一个消费者上绑定不同的路由Key
启动测试(收到不同的消息)
通配符模式,关于通配符模式跟路由模式差不多,只需在绑定的路由key上指定模糊匹配即可,让队列在绑定 Routing key 的时候使用。
匹配规则如下
# 匹配一个或多个词
* 匹配不多不少恰好1个词
关于其他的一些配置,下次再聊
新年快乐,明年见