消息队列(Message Queue)是分布式系统中最重要的中间件之一,在服务架构设计中被广泛使用。
1.11.1 通信模式与用途
消息中间件构建了这样的通信模式:一条消息由生产者创建,并被投递到存放消息的队列中,消费者从队列中读取这条消息,于是生产者与消费者完成了一次通信。这种通信模式在现实生活中很常见,典型的例子是E-mail通信:
住在北京的张三想把一个重要但不紧急的消息告诉住在上海的李四,张三给李四打电话,但是李四正在忙其他的事情而未接电话,张三为了把消息传达给李四,只能不停地拨打电话直到李四接听,这无疑浪费了张三大量的时间。于是,张三选择将消息使用E-mail的方式发送,他只需要把邮件投递到李四的收件箱中就可以去忙其他的事情了,而不用去管李四是否繁忙,E-mail系统保证只要李四空闲下来查看收件箱,就必然会收到张三的消息。对于消息中间件而言,张三和李四分别是生产者和消费者,E-mail系统就是消息队列。
消息队列的通信模式为生产者和消费者带来了便捷性,如下所述。
◎ 生产者将消息投递到消息队列中就单方面完成了消息通信,比如张三只需要发送邮件,而不用等待李四阅读邮件。
◎ 消费者在自身有能力消费消息时才从消息队列中拉取新消息,比如李四今天非常忙碌,那么他可以明天再登录E-mail系统阅读邮件。
正是因为消息队列为生产者和消费者提供了便利,所以它被广泛应用于分布式系统。下面介绍消息队列的几个核心用途。
1. 异步化
在未使用消息队列的系统中,一些非必要的业务逻辑以同步方式运行,导致请求处理耗时较大。比如图1-48所示的业务场景,一个用户请求需要串行地经过A、B、C、D四个服务处理,其中,A服务是此业务场景的核心服务,请求处理仅需10ms;B、C、D服务是非核心服务,请求处理时间分别是200ms、300ms、100ms。所以一个用户请求需要耗时610ms才能得到响应。
使用消息队列后,A服务可以将请求相关消息写入消息队列,然后直接返回响应消息,而不用关心B、C、D服务是否已经处理请求,以及是否遇到故障;B、C、D服务异步地从消息队列中拉取消息进行相应的业务逻辑处理。这样一来,用户请求的响应时间被大幅降低到10ms,如图1-49所示。
2. 流量削峰
通过 E-mail 系统,李四可以根据自己是否有空来选择阅读或者不阅读收件箱中的邮件,以及阅读几封邮件。对于消息队列的消费者来说也是一样的,消费者服务完全可以根据自己的消息处理能力灵活地读取消息,这样的灵活度能有效提高服务的稳定性。消息队列使得消费者服务拥有处理请求的主动权,再也不用担心自己会被击垮了。举一个例子,A服务使用数据库作为处理请求的核心,当A服务面临流量高峰时,全部请求都会直接访问数据库,导致数据库宕机,进而A服务崩溃。如果请求并不要求立即执行,则可以先将请求写入消息队列,A服务根据自己的处理能力从消息队列中慢慢拉取消息进行相应的请求处理。
如图1-50所示,假设A服务1s仅可以处理100个请求,流量高峰时10000 QPS会直接击垮A服务,而通过消息队列的形式,A服务可以根据自己的请求处理速度来拉取消息,在整个链路上原来的请求量10000 QPS被平滑为100 QPS,这就是流量削峰。
3. 解耦
在未使用消息队列时,服务之间的耦合性太强,如果B服务想加入A服务的请求处理流程,则需要在A服务中实现对B服务的RPC逻辑。假设在系统中有3个服务,如下所述。
◎ 点赞服务:负责处理用户对文章的点赞请求,主要业务逻辑是为用户和文章建立已点赞的关系记录。
◎ 热点服务:根据每篇文章的被点赞次数,给出当前最热门的文章列表。
◎ 策略服务:分析每个用户的点赞文章类型,以便可以将同类型的文章推荐给该用户。
热点服务和策略服务都想实时获取用户点赞行为,为此,我们只能在点赞服务对用户点赞请求的处理逻辑中增加对这两个服务的RPC。如果将来有服务也想要收集用户点赞行为,或者策略服务下线,则需要改造点赞服务,于是所有依赖用户点赞行为的服务都与点赞服务形成了耦合,如图1-51所示。
在系统中引入消息队列后,这种耦合关系得到完全解耦:点赞服务将在处理用户点赞请求时顺便将点赞事件发送到消息队列,任何希望收集用户点赞行为的服务只需要被配置成这个消息队列的消费者,而不会对点赞服务有任何影响。
如图1-52所示,通过引入消息队列,点赞服务与其他服务彻底解耦,每个服务的负责人只需要专注于自己的服务,这样也解决了一个大规模后台中多部门或多人协作的职责分离问题,减少了事故的发生。
最后推荐这本书,可以细致的了解高并发系统设计
内容结构上可以分为三大篇
- 架构知识篇(第1~3章):作为全书的基础知识篇,首先介绍后台的关键组件构成以及机房的搭建思路,然后介绍后台在应对高并发的读/写请求时通用的处理手段,最后介绍如何通过通用的服务治理手段来保障后台的高质量运行。
- 基础服务设计篇(第4~6章):主要讲解基础服务的架构设计,这里选取的基础服务几乎是所有互联网后台都需要的专门系统,包括唯一ID生成器、用户登录服务和海量推送系统。
- 核心服务设计篇(第7~13章):主要讲解在常见的社交互动场景中所需核心服务的架构设计,包括内容发布系统、通用计数系统、排行榜服务、用户关系服务、Timeline Feed服务、评论服务和IM服务。