消息队列

消息队列

当不需要立即获得结果,但并发量需要进行控制的时候,就需要使用消息队列的时候。主要解决如下问题

  • 应用耦合
  • 异步处理
  • 流量削峰
  • 消息驱动的系统

使用场景

异步处理

多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间

对于某个应用需要用户注册,并发送邮件和短信验证,

1.串行执行

1
用户注册 --> 注册信息写入 --> 发送注册邮件 --> 发送注册信息

2.并行处理

1
2
3
4
用户注册 --> 注册信息写入 --> 发送注册信息
                          | 
                          |
                          --> 发送注册邮件

3.消息队列

1
2
3
4
用户注册 --> 注册信息写入 --> 消息队列 --> 发送注册短信
                                   |
                                   |
                                   --> 发送注册邮件

在写入消息队列后,立即返回成功给客户端,而写入消息队列的时间可以忽略不计,所以比前俩者更加快速

应用耦合

多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败

用户上传一张图片,人脸识别需要识别,通常的做法如下

1
图片上传系统  --  调用接口  --> 人脸识别

可能带来如下问题

  • 人脸识别调用失败,导致图片上传失败
  • 延时高,需要人脸识别处理完成再返回结果,及时不需要立即知道结果
  • 图片上传系统与人脸识别之间相互调用,需要耦合

改为使用消息队列

1
图片上传系统 -- 生产 --> 消息队列 <-- 消费 -- 人脸识别系统

这样,图片上传系统就不需要关心人脸识别系统何时、怎样处理这些图片,人脸识别系统也可以自由处理这些图片信息

限流削峰

广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况

1
用户请求 -- 写入 --> 消息队列 <-- 读取 -- 业务处理系统

这样,消息队列实际上起到了缓冲的作用

消息驱动的系统

类似应用的耦合,避免直接调用下一个系统导致当前系统的失败,子系统对于消息的处理可以更加灵活

1
图片上传系统 -- 生产 --> 消息队列 <-- 消费 -- 人脸识别系统 -- 生产 --> 消息队列 <-- 消费 -- 对账系统

模式

包括点对点和发布/订阅模式

点对点模式

包括三个角色

  • 消息队列
  • 生产者
  • 消费者
1
生产者 -- 生产 --> 消息队列 <-- 消费 应答 -- 消费者
  • 每个消息只有一个消费者
  • 生产者和消费者之间没有依赖
  • 消费者在成功接收消息之后向队列应答成功,以便队列删除当前接收的消息

发布订阅模式

角色如下

  • 角色主题
  • 发布者
  • 订阅者
1
2
3
4
生产者 -- 生产 --> 消息队列  <-- 订阅 -- 消费者1
                      |                   ^
                      |                   |
                      -- 消息 -->     -- --  
  • 每个消息可以有多个订阅者
  • 发布者和订阅者之间有时间上的依赖,
  • 为了消费消息,订阅者需要提前订阅该角色的主题,并保持在线运行

常用消息队列介绍

RabbitMQ

  1. 可靠性: 提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制;

  2. 灵活的路由: 消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用;

  3. 消息集群:在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用;

  4. 队列高可用:队列可以在集群中的机器上进行镜像,以确保在硬件问题下还保证消息安全;

  5. 多种协议的支持:支持多种消息队列协议;

  6. 服务器端用Erlang语言编写,支持只要是你能想到的所有编程语言;

  7. 管理界面: RabbitMQ有一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面;

  8. 跟踪机制:如果消息异常,RabbitMQ提供消息跟踪机制,使用者可以找出发生了什么;

  9. 插件机制:提供了许多插件,来从多方面进行扩展,也可以编写自己的插件;

  10. 支持万级别的并发

kafka

这个算是当前海量并发下最常用的消息队列了,支持百万级别并发,使用scala语言编写,支持主流的java各种技术框架

RocketMQ

Redis

实际上,redis作者都不建议redis做消息队列,(^_^)/(ㄒoㄒ)/~~,但是redis确实支持了,不过确实不建议用作高并发场景