消息队列相关

消息队列(message queue), 是分布式系统中重要的组件,其通用的使用场景可以简单的描述为

当不需要立即获得结果,但是并发量又需要进行控制

消息队列主要解决了应用耦合,异步处理,流量削峰等问题。
目前较为使用广泛的消息队列有 RabbitMQ, RocketMQ, ActiveMQ, Kafka, ZeroMQ, MetaMq 等。部分数据库 redis, Mysql 以及 phxsql 也可以实现消息队列的功能。

使用场景

消息队列在实际应用中包括如下几个场景

  • 应用耦合
    多个应用通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败
  • 异步处理
    多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时延
  • 限流削峰
    广泛应用于瞬时高流量场景,避免流量过大导致应用系统挂掉的情况
  • 消息驱动
    系统分为消息队列,消息生产者,消息消费者,生产者负责产生消息,消费者(多个)负责对消息进行处理

应用解耦合

具体例如当用户上传一张图片,服务器要对其标识人脸,一般是上传后由上传系统调用人脸识别 API, 但是在这个场景里面

  • 如果人脸识别 API 调用失败,那么图片上传也会失败
  • 用户其实不需要立即直到人脸识别结果
  • 图片上传系统与人脸识别系统之间互相调用,耦合度高

但是如果这里使用消息队列的话,比如上传系统将图片信息批次写入消息队列,直接返回,而人脸识别 API 则定时从消息队列取任务,完成对新增图片的识别。
那么此时上传系统就与人脸系别解耦,图片上传成功与否则与人脸识别 API 无关

限流削峰

通常用于瞬时流量大的场景,比如秒杀,抢购等活动。此时由于瞬时访问量过大,服务器接受过大,导致流量暴增,可能会导致系统崩溃,而加入消息队列后,系统可以从消息队列中取数据,相当于消息队列做了一次缓冲。

  • 请求先入消息队列,而不是由业务系统直接处理,减少了业务系统压力
  • 队列长度可以做限制,比如抢购活动只有 100 个名额,那么 100 之后请求就可以直接抛弃,返回活动已结束或者商品已售完等消息

消息队列的两种模式

消息队列包含两种模式,点对点模式(point to point, queue) 和发布/订阅模式(publish, subscribe, topic)

点对点模式

点对点模式包括以下三个角色

  • 消息队列
  • 生产者
  • 消费者

消息发送者生产消息发送到 queue 中,消费者从 queue 中取出并且消费消息。消息被消费之后, queue 中不再存储,所以消息接受者不可能消费到已经被消费的消息

点对点模式特点

  • 每个消息只有一个消费者,即消息不能重复消费
  • 生产者和消费者之间没有依赖关系,即消费者的正常与否并不影响发送者的功能
  • 消费者在成功接受消息后需向队列应答成功,方便消息队列删除当前接受的消息。

发布/订阅模式

发布/定阅模式包含以下三个角色

  • 角色主题(topic)
  • 发布者(publisher)
  • 订阅者(subscriber)

发布者将消息发布到 topic, 系统将这些消息传递给多个订阅者

发布/订阅模式特点

  • 每个消息可以有多个订阅者
  • 发布者和订阅者之间有时间上的依赖性,针对某个主题(topic) 的订阅者,必须创建一个订阅者之后,才能消费发布者的信息
  • 为了消费信息,订阅者需要订阅该角色主题,并保持在线运行

常用消息队列

  • RabbitMQ
  • ActiveMQ
  • RocketMQ
  • kafka

之间对比可见下图,原图来自腾讯

message_queue