关于消息中间件的一些整理

为什么使用消息中间件?

  1. 解耦
    耦合性太强的话可以将消息写入消息队列,需要消息的系统自己从消息队列中订阅。
  2. 异步
    将消息写入消息队列,非必要的业务逻辑可以以异步的方式运行,加快主体业务的速度。
  3. 削峰
    并发量大的时候,所以的请求都直接对数据库,造成数据库异常,这个时候可以先把请求放入消息队列中,慢慢读取。

使用了消息队列有什么缺点?

  1. 系统可用性降低

    如果消息队列挂掉了,系统肯定就不行了。

  2. 系统复杂性增加

    加入消息队列需要考虑一些新的东西,比如一致性问题,如何保证消息不被重复消费,如何保证消息可靠性传输等。

常见的消息队列比较(如何选型)?

特性ActiveMQRabbitMQRocketMQkafkaZeroMQ
开发语言javaerlangjavascalac
单机吞吐量万级万级10万级10万级最高
时效性ms级us级ms级ms级以内
可用性高(主从架构)高(主从架构)非常高(分布式架构)非常高(分布式架构)
功能特性成熟的产品,在很多公司得到应用;有较多的文档;各种协议支持较好基于erlang开发,所以并发能力很强,性能极其好,延时很低;管理界面较丰富MQ功能比较完备,扩展性佳只支持主要的MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据准备的,在大数据领域应用广。内存中使用,不支持数据持久化,金融场景比较多见。

主要有两点:

  1. 中小型软件公司,建议选rabbitMQ,e语言天生具备高并发的特性,管理界面用起来十分方便。但是e语言的个性化定制不容易。不选rocketmq和kafka的原因是,数据量没那么大,kafka功能不完备,rocketmq是阿里的,也是不容易进行rocketmq的定制性开发。
  2. 大型软件公司,可以在rocketMQ和kafka之间二选一。有足够的资金搭建分布式环境,也具备足够大的数据量。如果有日志采集功能,首选kafka。

如何保证消息队列高可用?

以RocketMQ为例:他的集群就有多master模式、多master多slave异步复制模式、多master多slave同步双写模式。 感觉这里无非就是多台机器,和zookeeper什么类似。

如何保证消息不被重复消费(如何保证消息队列的幂等性?)

正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除。只是不同的消息队列发出的确认消息形式不同,例如RabbitMQ是发送一个ACK确认消息,RocketMQ是返回一个CONSUME_SUCCESS成功标志,kafka实际上有个offet的概念,简单说一下,就是每一个消息都有一个offset,kafka消费过消息后,需要提交offset,让消息队列知道自己已经消费过了。
如果因为网络传输等故障,确认消息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他消费者。
如何解决?这个问题针对业务场景来答,分以下三种情况:

  1. 比如,你拿到这个消息做数据库的insert操作,那就容易了,给这个消息做一个唯一的主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。
  2. 再比如,你拿到这个消息做redis的set的操作,那就容易了,不用解决,因为你无论set几次结果都是一样的,set操作本来就算幂等操作。
  3. 如果上面两种情况还不行,上大招。准备一个第三方介质,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis.那消费者开始消费前,先去redis中查询有没有消费记录即可。

如何保证消费的可靠性传输?

我们在使用消息队列的过程中,应该做到消息不能多消费,也不能少消费。如果无法做到可靠性传输,可能给公司带来千万级别的财产损失。可靠性传输可以从这三个角度来分析。

  • 生产者弄丢数据
  • 消息队列弄丢数据
  • 消费者弄丢数据
  1. 生产者丢数据

从生产者弄丢数据这个角度来看,RabbitMQ提供transaction和confirm模式来确保生产者不丢消息。

transaction机制就是说,发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事务就会回滚(channel.txRollback()),如果发送成功则提交事务(channel.txCommit())。然而会造成吞吐量下降。

  1. 消息队列丢数据
    处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。

  2. 消费者丢数据

消费者丢数据一般是因为采用了自动确认消息模式。这种模式下,消费者会自动确认收到信息。这时rabbitMQ会立即将消息删除,这种情况下,如果消费者出现异常而未能处理消息,就会丢失该消息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值