消息队列介绍

本文将介绍大名鼎鼎的消息队列(MQ)的原理,应用场景和常见问题。

日常开发中,可能会经常遇到这几类问题:

  1. 系统中批量更新(增,删,改)功能接口,如果业务比较复杂,加之数据量庞大,这类同步操作是很耗时的,这时候需要进行异步处理
  2. 电子商务网站在促销活动时,会在短时间内高并发,需要削平高峰期的并发事务
  3. 为了提高系统的可扩展性,希望各个模块之间不存在直接调用,开发低耦合的系统,对各个模块之间进行解耦

以上场景,都可以使用消息队列有效解决。

什么是消息队列?

消息(Message)是指在应用间传送的数据(比如字符串,json等),消息队列(Message Queue,简称MQ)是一个古老的计算机术语,UNIX进程间通信就用到了消息队列技术:一个进程把数据写入某个特定队列中,其它队列读取特定队列中的数据实现异步通信。而现在我们所说的MQ通常指的是独立的消息队列中间件,利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。

传递模式

消息队列一般有两种传递模式:

  1. 点对点(Point to Point,简称PTP):消息生产者发送消息到队列,消费者从队列中接收消息。消息被消费以后,queue中不再存储,queue支持存在多个消费者,但是一个消息只能被一个消费者消费。
  2. 发布 / 订阅(Pub / Sub):发布订阅(一对多)广播形式,消息发布者将消息发布到某个主题(Topic),消息订阅者从主题中订阅消息(得到消息的拷贝),一个消息可以同时被多个消费者订阅,并会被所有订阅者消费。

组成

  1. Broker: 消息服务器,作为server提供消息核心服务
  2. Producer:消息生产者,业务的发起方,生产消息传输给broker
  3. Consumer:消息消费者,业务处理方,负责从broker获取消息并进行业务逻辑处理
  4. Topic:主题,Pub/sub模式下 消息统一汇聚地,不同生产者向topic发送消息,由MQ服务器分发到不同订阅者,实现消息的广播。
  5. Queue:队列,PTP模式下,特定生产者向特定队列发送消息,消费者订阅特定的queue完成指定消息的接收与消费。
  6. Message:消息体,根据不同通信协议定义的固定格式编码数据包,来封装业务数据,实现消息的传输。

消息队列的作用

介绍几个消息队列的重要作用:

  1. 解耦:传统的软件开发模式,各个模块之间相互调用,数据共享,每个模块都要时刻关注其他模块的是否更改或者是否挂掉等等,使用消息队列,可以避免模块之间直接调用,将所需共享的数据放在消息队列中,对于新增业务模块,只要对该类消息感兴趣,即可订阅该类消息,对原有系统和业务没有任何影响,降低了系统各个模块的耦合度,提高了系统的可扩展性
  2. 异步:消息队列提供了异步处理机制,在很多时候应用不想也不需要立即处理消息,允许应用把一些消息放入消息中间件中,并不立即处理它,在之后需要的时候再慢慢处理。
  3. 削峰:在访问了骤增的场景下,需要保证应用系统的平稳性,但是这样突发流量并不常见,如果以这类峰值的标准而投放资源的话,那无疑是巨大的浪费,使用消息队列能够使关键组件支撑突发访问压力,不会因为突发的超负荷请求而完全崩溃。消息队列的容量可以配置的很大,如果采用磁盘存储消息,则几乎等于“无限”容量,这样一来,高峰期的消息可以被积压起来,在随后的时间内进行平滑的处理完成,而不至于让系统短时间内无法承载而导致崩溃,在电商网站的秒杀抢购这种突发性流量很强的业务场景中,消息队列的强大缓冲能力可以很好的起到削峰作用。

消息队列技术选型

现在有很多主流的消息中间件,包括:ActiveMQ, RabbitMQ,Kafka, RocketMQ,Redis。选型时要结合具体的应用场景和自身的业务需求,从功能、性能、运维、可靠性+可用性等维度进行多重考量。

ActiveMQ

Apache出品,Java开发,目前所占的市场份额不多。

RabbitMQ

Erlang语言实现AMQP协议的消息中间件,并发能力很强,性能及其好,延时很低(达到微妙级),特点:可靠性,可用性,扩展性,功能丰富。

Kafka

LinkedIn使用Scala开发的分布式,多分区,多副本且基于zookeeper协调的分布式消息系统,提供了超高的吞吐量,毫秒级延迟,极高的可用性和可靠性。

RocketMQ

阿里出品,Java开发,高吞吐,高可用,适合大规模分布式应用,经过多次双十一的洗礼,实力不容小觑。

所谓的**消息中间件大道至简:一发一存一消费,没有最好的消息中间件,只有最合适的消息中间件。 **

带来的问题

引入消息队列后,我们需要考虑哪些问题呢?

1. 消息堆积

这是一个很常见的问题,如果消息消费的时间太久,或者服务器故障,导致消息堆积。

2. 消息丢失

消息堆积一个处理方案就是给消息加上超时时间判定,这样就会衍生一个问题,当消息堆积,处理完成之后,就会存在一定消息的丢失,或者服务器宕机也会导致消息丢失,需要针对此类问题做好应对方案。

3. 消息准确消费

保证消息被准确消费,且不存在重复消费的问题。

推荐大家的项目开发中使用消息队列,并不是“杀鸡焉用牛刀”的问题,而是未雨绸缪,随着项目不断发展,你终将从消息队列中获益。
以上。

最后,祝大家新年快乐!

posted @ 2020-01-01 23:31  yabea  阅读(1701)  评论(1编辑  收藏  举报