常见MQ总结与汇总

一、MQ的作用和应用

MQ在实际生产中用于应用解耦,异步消息,流量削峰,消息通讯等功能。
流量削峰的意思就是,当有大批量的请求访问服务器时,服务器或数据库会崩溃。这时把大批量的请求发送到MQ中,MQ可以支撑住大量的访问。然后服务器或数据库在按照批次慢慢拉取MQ中的数据,这样不会造成服务器或数据库的崩溃。这就叫削峰填谷。

二、常见MQ比较

常见MQ总结与汇总_第1张图片
这是官方的比较。通过自己的学习,对几种常见的MQ的比较如下:
ActiveMQ:
比较古老的项目的维护,可能会应用到ActiveMQ。新的项目应用很少。单从ActiveMQ的性能上来说,笔者认为其和RabbitMQ是不分伯仲的。现在很少应用的原因笔者认为是其功能较为单一造成的。

RabbitMQ:
对于数据量不是特别大的业务场景,RabbitMQ是最为合适的选择。从功能方面说,RabbitMQ提供了程序员在MQ使用过程中各种需求的机制,功能还是比较丰富的。从使用成本上考虑,RabbitMQ相比于RocketMQ,Kafka对服务器的要求都比较低。所以对于大部分中小型企业来说,都选择了RabbitMQ作为了消息中间件。

Kafka:
如果单是从作为MQ来使用的话,选择Kafka作为MQ笔者认为这不是一个合理的选择。Kafka用于MQ使用的话,其功能性相对来说还是比较单一的。比如说,Kafka并没有提供类似于RabbitMQ中死信队列的机制,总体感觉就是Kafka在收发消息中只实现了基本的功能,没有为程序员提供各种需求的处理机制。
但是Kafka在大数据领域发挥出了特别的作用。其流处理功能等特性,被大数据广泛应用。所以笔者说单纯作为MQ使用的话,Kafka不是第一首选。但是Kafka涉及的生态比较多,所以在实际生产中,我们常常看见Kafka既作为了MQ在使用,又作为了数据治理的工具来使用。

RocketMQ:
上面说到单纯用于MQ使用,Kafka不是 第一选择,那么在大数据量的场景下使用MQ,应该如何选择呢?没错,使用RocketMQ。虽然RocketMQ的前身出自Kafka。但是在Kafka的基础上,衍生出了很多MQ独有的特性和功能。RocketMQ对于服务器的要求较高,成本较大,所以没有大数据量的业务场景下,还是不要为了装逼而选择RocketMQ了,比较老板心疼的是钱,而不是技术的逼格有多高。

EMQX:
EMQX相当于物联网领域的Kafka,支持大数据量业务场景。其实现了MQTT协议,并在此基础上扩展出很多MQ的特性和机制。对于单纯的java程序员来说,可能对EMQX并不熟悉,但是EMQX也可以作为一款高性能MQ,满足大多数的业务场景。

三、MQ中的幂等性解决方案

虽然MQ自身做了消息的ACK机制。但是在网络波动等情况下,难免会造成消息的重复发送和重复消费。这就需要我们在业务代码中,进行幂等性的判断和校验了。
幂等性解决方案
幂等性的解决方案我们在以后的文章单独讨论。最简单的幂等性方案就是生成唯一ID,在业务代码中通过唯一ID进行去重判断。这个唯一ID的生成策略是多种多样的。比如笔者在使用Kafka实现幂等性时,将消费者的某个主题下的Offset作为唯一ID去进行去重,以达到防止重复消费的目的。

四、MQ共性与特性

通过研究RabbitMQ、RocetMQ、Kafka、EMQX几个MQ的中间件,我们来总结一下MQ中间件的共性和这几个MQ中间件的特性。掌握共性是为了在繁多的MQ中间件中,我们再遇到新的MQ时,可以很快的掌握其套路。掌握特性是为了在碰到负责的业务场景时,可以知道哪个MQ的特性可以自动支持业务问题的解决。

4.1 生产者
对于MQ的生产者而言,具备的特征有:
同步发送,
异步发送,
单向发送(部分MQ有此功能),
批量发送消息 ,
ACK消息确认机制:不同的MQ或协议确认机制有所区别,详见各自的MQ。

4.2 消费者消费消息

对于消费者而言,最主要的就是消费成功的消息,不再重复消费。消费失败的消息,需要进行再次消费和处理。不同的MQ有不同的机制:
RabbitMQ:消费者手动或自动确认消息消费后,消息才会删除。还提供了拒绝和Nack策略。被拒绝或Nack的消息会进入死信队列。由此可以看出RabbitMQ扩展了很多机制和功能,让程序员应对各种出现的可能。

Kafka:
Kafka消费者通过偏移量的提交,来记录消费记录。所以Kafka消费者需要正确的提交偏移量,才能不重复读取数据,也不丢失数据。Kafka后面的偏移量会覆盖前面的偏移量,也没有提供死信队列等机制。所以程序员只能自行记录消费失败的偏移量,单独处理。由此笔者才说,Kafka单纯作为MQ使用的话,不是第一 首选。

RocketMQ:
RocketMQ也有偏移量的概念。RocketMQ消费失败的消息,会进入重试队列进行重复消费,默认消费16次还是失败时,会进入死信队列。RocketMQ的死信消息不能再由消费者消费,需要程序员手动进行处理。

4.3 消息发布模式

下面我们对比一下几个MQ消息发布模式:
RabbitMQ:
RabbitMQ遵循的AMQP协议。生产者发送消息到交换器,交换器根据路由键与队列的绑定关系,将消息路由到相应的队列。消费者通过订阅队列来进行消息的消费。不同的交换器类型,根据不同的路由规则,将消息进行路由。

Kafka:
Kafka发送消息到Topic的某个分区下,按照轮询的方式或其他规则对分区进行消息分发。消费者群组消费时对分区上的消息进行消费。

RocketMQ:
RocketMQ发送消息给topic的某个MessageQueue。生产者可以指定Queue进行消息的发送。生产者可以指定TAG或userProerty。消费者对消息的消费 分为集群模式和广播模式。集群模式消费一个Queue上的消息。广播模式一个消费者消费某个Topic下所有的QUEUE的消息。

EMQX:
EMQX遵循MQTT协议。MQTT协议本身是订阅/发布模式。支持通配符发送或订阅主题。MQTT相比于RabbitMQ或RocketMQ而言功能还是相对单一的。EMQX在物联网的应用比较广泛。

4.4 MQ服务高可用

**RabbitMQ集群:**采用镜像集群,用Haproxy+keepAlive搭建集群,实现RabbitMQ的数据备份和高可用。
Kafka:
Kafka集群通过ISR机制,最小同步副本机制,不完全首领机制确保数据的高可用。
RocketMQ:
RocketMQ集群通过多主多从的模式,确保数据的高可用。
EMQX::集群模式,确保高可用。

4.5 ACL机制
ACL指身份认证,不同的MQ都有ACL身份认证机制。实际生产中根据需要是否开启ACL认证。
4.6 延时消息
在RocketMQ和EMQX中,有延时消息机制。其他MQ想要实现延时队列,得自己实现了。

4.7 死信队列
RabbitMQ和RocketMQ都有死信队列机制。

总结

通过上面的总结,可以看出,RabbitMQ和RocketMQ,是功能最全,性能最好的两个MQ选择。

你可能感兴趣的:(日常开发总结,队列,java,分布式,kafka)