微服务使用异步通信时,通常使用消息队列。消息队列能确保不同微服务间可靠稳定的通信,在系统内可有效管理和监控消息,且不会丢失。
根据数据量和功能的不同,可选择的消息队列中间件有很多,今天我们着重比较最受欢迎的三款,RabbitMQ、Kafka 和 Redis。
在比较之前需要先了解一些基础知识
微服务通信:同步和异步
微服务间的通信方式通常有两种:同步和异步。以HTTP的REST协议为基础,一般在同步通信中,调用者发出消息后需要等待响应;在异步通信中,在发出消息后不需要等待响应,所以异步通信更适用于分布式系统。
当然这只是理论上的,实际构建平台的时候应考虑不同的参数,比如基础的网络设施,延迟、规模、目的等等的实际情况。异步通信架构会变复杂,需要再搭建更多的中间件,但无论如何,微服务使用异步通信利大于弊。
异步通信优势
首先,异步通信最大的特点是非阻塞;其次,异步比同步支持更大的扩展性;最后,如果微服务崩溃,异步通信机制提供了各种恢复技术,能更好处理崩溃有关的错误。因为相互通信的微服务不需要相互了解,整个微服务都是松耦合的。
还有,异步通信能提高系统开发、监控等的可扩展能力。
怎么选择消息队列平台呢?
这里有三个标准:
并发规模,指系统每秒能发送的最大消息数。
数据持久性,指恢复消息的能力。
消费者模式,指消息发送模式是点对点还是一对多(发布订阅模式)。
比较
RabbitMQ (AMQP)
规模:大概能达到每秒5万条消息。
持久性:支持持久性和瞬态消息。
模式:点对点和一对多两者都有。
RabbitMQ 发布于 2007 年,是最早的开源消息队列中间件之一,使用高级消息队列协议 (AMQP),通过点对点和发布订阅模式传递消息,旨在支持复杂的路由逻辑。
RabbitMQ 支持所有主流语言,包括 Python、Java、.NET、PHP、Ruby、JavaScript、Go、Swift 等。
在持久性上可能会出现一些性能问题。
Kafka
规模:每秒最多可以发送一百万条消息。
持久性:支持。
模式:只支持一对多。
Kafka由领英发布于 2011 年,其特点是高吞吐量和低延迟。常应用于分布式流媒体平台。
Kafka 支持所有主流语言,包括 Python、Java、C/C++、Clojure、.NET、PHP、Ruby、JavaScript、Go、Swift 等。
Redis
规模:每秒最多可以发送一百万条消息。
持久性:采用内存储存数据,基本没有持久性。
模式:点对点和一对多两者都有。
Redis 与其他消息队列略有不同。从本质上讲,Redis 是一种内存数据库,可用作高性能键值对存储或消息队列。另外,Redis几乎没有持久性,而且数据可以设置过期时间,一到过期时间数据会像缓存一样被自动销毁,如果需要保存数据需要转存到其他数据库中。Redis非常适合实时数据处理。
最初,Redis既没有点对点也没有一对多模式。但是从 Redis5.0 引入了pub-sub功能,Redis就真正拥有了消费者模式。
建议
以上介绍了 RabbitMQ、Kafka 和 Redis 的一些特性。这三者都是同类中的佼佼者,但他们的运作方式却大不相同。以下是针对不同应用选择消息队列的建议:
缓存消息:Redis
Redis 本身是内存数据库,非常适合不需要持久化的短期消息的应用。如果持久化要求不高,又容忍数据一定程度的损失,Redis就很适合。
海量数据:Kafka
Kafka 是一个高吞吐量的分布式队列,专为长时间存储大量数据而生。Kafka 非常适合需要持久性的一对多应用。
复杂路由:RabbitMQ
RabbitMQ 是一个较旧但成熟的中间件,可支持很多复杂路由的特性和功能。当应用要求的并发数量不是非常高的时候,RabbitMQ是个不错的选择。