消息队列(Message Queue)可以说是分布式系统中非常重要也是非常古老的一个技术。顾名思义,它最主要的功能就是收发消息,但是在现代的分布式系统中它不仅仅是为了解决系统之间的通信问题,还肩负着其他很多职责。
目前,开源的消息队列框架有很多,我们耳熟能详的有Kafka、ActiveMQ、RabbitMQ和RocketMQ等等。这些框架作为开源框架,使用者可以方便的进行深度定制以满足需求。
但随着目前云计算的流行,越来越多的公司开始直接使用云计算公司提供的各种组件进行系统的搭建,那么直接使用云厂商提供的消息队列可以很方便的对已经搭建好的服务进行扩展。此外,对于大部分不需要对消息队列进行深度定制的用户,可靠并且有专人维护的云上的消息队列服务也是一种经济实惠的选择。微软作为领先的云计算厂商,提供了多种消息队列,满足用户的不同使用场景。
作为服务的使用者,我们只有知道了各种消息队列的特性及使用场景,才能在技术选型时做出合理的选择。作者在本文中首先会对在系统中使用消息队列的好处进行简单总结,然后对目前Azure已经存在的各种消息队列进行总结和比较,希望读者能读完本文后对云计算中的消息队列服务有一个概括性的了解。
使用消息队列的优势
减少响应时间
在响应客户请求时,对于比较耗时的操作,我们并不希望阻塞用户。所以通过消息队列,可以把这类请求先暂存起来,客户可以得到及时的反馈,然后后端服务再从消息队列中拿到消息进行处理。
增加可靠性
如下图所示,只要后端发生宕机,那么用户看到的是整个系统宕机。但是当我们引入消息队列后,如果后端宕机,我们依然可以先把客户的请求暂时存放到消息队列中去,但是用户依然会得到成功的回应。当后端服务恢复时,可以直接从消息队列中获取消息处理客户请求。
可以方便进行独立扩展
web服务器对突然增多的请求更加敏感,尽管可以利用云计算的自动扩展技术(Autoscaling)自动提升web服务器的数目,但是自动扩展后的web服务器也不能马上开始处理这些增多的请求。如果我们引入消息队列,就可以让web服务器把一些工作负载放置到任务队列中,然后后端服务从该队列中拿取消息进行处理。通过消息队列将web服务器和后端服务分离后,如果我们发现服务器或者后端服务有更多的任务需要处理,我们就可以分别进行扩展,而不是一起扩展,从而达到了经济高效的扩展。
以上图片来自https://docs.microsoft.com/en-us/aspnet/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/queue-centric-work-pattern
Azure消息队列总结
Azure作为成熟的,目前较为流行的云计算平台,提供了多种多样的消息队列服务,以满足用户在不同场景需求下的要求,目前在Azure中主要存在如下的一些消息队列服务
Azure Storage Queue
Azure Service Bus Queue
Azure Service Bus Topic
Azure Event Hubs
Azure IoT Hub
Azure Event Grid
Azure Notification Hubs
(1) Azure Storage Queue
Azure Storage Queue早在2010年就开始上线提供服务,是Azure最早的消息队列服务。由于它的简单易用,以及相比于其他消息队列的性价比,很适合刚开始使用云端消息队列的客户使用。它的主要特点有如下三个
简单
高性价比
支持大量消息在队列中
不过需要注意的是Azure Storage Queue并不保证消息的顺序以及它是“至少发送一次”的消息投递模型。所以,我们在使用这个服务时需要考虑同一个消息收到多次的可能。在如下场景中可以考虑使用Azure Storage Queue
应用一定会存储超过80GB消息
应用需要在队列内跟踪消息的处理过程
需要保留应用中所有队列的事务执行日志
(2) Azure Service Bus
Azure Service Bus围绕着云计算应用内以及应用之间相互传递消息的场景进行构建,主要提供两种队列服务,Queue和Topic。相比于Azure Storage Queue,Azure Service Bus Queue是一种更为健壮的消息队列服务。它提供先进先出(FIFO)的消息投递模型。与Azure Storage Queue一样,在Azure Service Bus Queue中我们一样需要考虑重复消息的处理。而Azure Service Bus Topic则增加了一些更为高级的消息队列特点。最大特点是实现了订阅/发布的消息模型,可以实现多个订阅者订阅某一类消息的场景。在如下场景我们可以考虑使用Azure Service Bus
要求消息按照先进先出的顺序进行投递
应用存储的消息不会超过80GB
你的应用需要处理的单个消息大小超过64KB但不超过256KB
需要接收不同类型的消息进行处理
(3) Azure Event Hubs
Event(事件)相比于message(消息)是一个更轻量级的概念。Message往往指一个原生的数据,Event指一种轻量级的状态改变的通知。也正是因为事件的轻量级,Azure Event Hub可以每秒接受和处理百万级别的事件。此外,Event Hub还可以无缝的和其他事件系统进行整合。正因为这样,Event Hub往往作为事件处理流水线中的入口点,来对事件的生产者和消费者进行解耦。在如下场景我们可以考虑使用Azure Event Hub
构建大数据处理系统的事件入口点
需要跟Kafka等既有系统进行整合
有连续型事件需要处理
(4) Azure IoT Hubs
Azure IoT Hubs是基于Azure Event Hubs构建,但相比于Azure Event Hubs增加了双向通信的功能。而在我们之前介绍的其他队列服务中,消息只能单向的发向云端。而在物联网应用中,云端可以向设备发送事件及指令是非常有用及重要的。因为这样云端可以作为设备之间进行通信的中继,也可以在云端对一些指令进行多个设备的推送。在如下场景我们可以考虑使用Azure IoT Hub
连接和管理10亿级别的物联网装置
需要在物联网设备和云端建立可以互相信任的双向通信
需要使用云端服务来注册、管理和保证物联网设备的安全性。
(5) Azure Event Grid
Azure Event Grid是云原生的消息服务用来更容易的构建基于事件的系统。他跟Azure Service Bus Topic一样是基于发布者/订阅者的模型。发布者只是负责发布事件,但并不会针对事件是否被处理进行进一步跟踪,订阅者根据提前定义好的topic进行事件的接收和处理。
Event Grid跟Azure的服务已经深度整合,并且也和第三方服务进行了整合,可以有效并且可靠地从Azure的事件源和非Azure的事件源将事件进行路由转发,然后将事件分发到注册的订阅方。此外,它也消除了订阅方需要不断拉取消息的必要,从而简化了事件订阅方的操作。
因此我们在如下场景考虑使用Azure Event Grid
需要一个与Azure和其他第三方云服务深度整合的事件分发系统
需要构建支持事件驱动的云原生、Serverless、微服务应用时
Azure Notification Hub是一种不同的消息服务。它被用来从Azure的服务发送原生的移动端推送消息给移动装置上的原生应用。它提供了一个很好的抽象层,开发人员不需要关心这个消息如何被发送,只需要将推送发给Azure Notification Hub,那么它自己就会将消息推送给开发人员指定系统上的APP。
总结
我们通过上面对Azure不同云端的消息服务介绍,可以发现目前主流云厂商还是提供了很多消息服务来满足不同客户的不同使用场景。虽然这些服务并不是开源的,但是对于初创公司快速搭建云端系统或者是传统公司向云端迁移,利用这样可靠的、高效的消息服务可以加快开发进度,保证产品的稳定性,也可以将更多的精力放在如何对业务进行构建上。如果接下来有机会我还会对本文中出现的不同消息服务进行更深入的讲解,来帮助广大读者更好的进行云端消息服务的选择。