消息队列
当不需要立即获得结果,但并发量需要进行控制的时候,就需要使用消息队列的时候。主要解决如下问题
- 应用耦合
- 异步处理
- 流量削峰
- 消息驱动的系统
使用场景
异步处理
多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间
对于某个应用需要用户注册,并发送邮件和短信验证,
1.串行执行
1 | |
2.并行处理
1 | |
3.消息队列
1 | |
在写入消息队列后,立即返回成功给客户端,而写入消息队列的时间可以忽略不计,所以比前俩者更加快速
应用耦合
多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败
用户上传一张图片,人脸识别需要识别,通常的做法如下
1 | |
可能带来如下问题
- 人脸识别调用失败,导致图片上传失败
- 延时高,需要人脸识别处理完成再返回结果,及时不需要立即知道结果
- 图片上传系统与人脸识别之间相互调用,需要耦合
改为使用消息队列
1 | |
这样,图片上传系统就不需要关心人脸识别系统何时、怎样处理这些图片,人脸识别系统也可以自由处理这些图片信息
限流削峰
广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况
1 | |
这样,消息队列实际上起到了缓冲的作用
消息驱动的系统
类似应用的耦合,避免直接调用下一个系统导致当前系统的失败,子系统对于消息的处理可以更加灵活
1 | |
模式
包括点对点和发布/订阅模式
点对点模式
包括三个角色
- 消息队列
- 生产者
- 消费者
1 | |
- 每个消息只有一个消费者
- 生产者和消费者之间没有依赖
- 消费者在成功接收消息之后向队列应答成功,以便队列删除当前接收的消息
发布订阅模式
角色如下
- 角色主题
- 发布者
- 订阅者
1 | |
- 每个消息可以有多个订阅者
- 发布者和订阅者之间有时间上的依赖,
- 为了消费消息,订阅者需要提前订阅该角色的主题,并保持在线运行
常用消息队列介绍
RabbitMQ
-
可靠性: 提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制;
-
灵活的路由: 消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用;
-
消息集群:在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用;
-
队列高可用:队列可以在集群中的机器上进行镜像,以确保在硬件问题下还保证消息安全;
-
多种协议的支持:支持多种消息队列协议;
-
服务器端用Erlang语言编写,支持只要是你能想到的所有编程语言;
-
管理界面: RabbitMQ有一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面;
-
跟踪机制:如果消息异常,RabbitMQ提供消息跟踪机制,使用者可以找出发生了什么;
-
插件机制:提供了许多插件,来从多方面进行扩展,也可以编写自己的插件;
-
支持万级别的并发
kafka
这个算是当前海量并发下最常用的消息队列了,支持百万级别并发,使用scala语言编写,支持主流的java各种技术框架
RocketMQ
Redis
实际上,redis作者都不建议redis做消息队列,(^_^)/(ㄒoㄒ)/~~,但是redis确实支持了,不过确实不建议用作高并发场景