在系统架构中引入了消息队列时,出发点有很多。下面记录一些这方面的思考。
什么是消息队列
计算机科学里,消息队列和邮箱都是被用于进程间通信或同一进程内线程间通信的软件工程组件。它们使用队列传递报文-控制权或内容的通过。
上面是维基百科的解释,大概是消息队列产生的最初原因。它是两个独立资源之间的桥梁,避免了资源之间的直接依赖及相互影响。消息队列的两个主要元素是:消息和队列。
- 消息:独立的资源之间沟通内容的载体。生产者构造消息,消费者使用消息。
- 队列:存储消息的载体。生产者把消息放到队列中,消费者从队列中取出消息。
现在有很多种消息队列产品,MSMQ,RabbitMQ和ActiveMQ等等。参与过的项目中分别使用了MSMQ和RabbitMQ。
- MSMQ,微软的产品,不跨平台,支持离线发送消息。
- RabbitMQ,开源产品,跨平台,遵从AMQP,不支持离线发送消息。
什么是消息队列的优势
首先分析系统要求,系统架构通常需要考虑以下几点因素:
- 功能性需求
* 边界划分
* 信息存储
* 信息流转
* 重要性定义 - 非功能性需求
* 性能
* 稳定性
* 可维护性
* 安全性
以电商系统领取免费优惠券为类,每月15号早上10点发放固定数量的优惠券。这个功能对性能要求较高,并发百万。由于优惠券只会在用户的优惠券列表和购物车可以看到,因此发放优惠券允许几秒钟延迟。
此功能每个月只使用一次,通过消息队列可以达到削峰填谷的作用。如果申请和发放优惠券是一个完整的动作,则可能需要添加很多机器来满足每月一次的服务性能要求。
同样以电商系统的支付环节为例,当用户订单支付成功后需要完成以下功能:
- 发短信通知用户
-
仓库配送商品
当业务发展过程中需要添加一项新促销:订单支付后奖励用户积分。使用了消息队列后,这种情况变的非常简单,只需要创建一个积分服务并且订阅支付成功的消息。
通过上面的两个例子可以看到,利用消息队列可以获得以下好处: - 系统之间的解耦。
- 提高系统性能。
- 提高系统稳定性。
什么是消息队列的劣势
事情都有两面性,消息队列也不例外。不可避免的一个问题就是丢消息。为什么会丢消息呢?以RabbitMQ为例,有以下几种情况:
- 网络原因导致消息生产者无法创建消息
- 消息队列产品自身崩溃
- 消息队列服务重启
- 生产者或消息者自身崩溃,或着其它原因导致与消息队列产品的通信异常关闭
除了丢消息之外,由于其它原因导致消息的重复发送。
RabbitMQ提供了一些配置来确保消息至少发送一次,但是仍然避免不了丢消息。
总而言之,系统引入消息队列需要思考以下问题:
- 系统功能是否可以细分,并且允许异步完成。
- 系统功能是否支持幂等,避免消息重发引发异常。
- 系统功能是否允许丢消息,否则通过其它辅助设计确保消息不丢。
- 消息队列服务自身可用性
资料:
Message queue wiki
Reliable Delivery
RabbitMQ 高可用集群搭建及电商平台使用经验总结