消息队列相关

Posted cndarren

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息队列相关相关的知识,希望对你有一定的参考价值。

一、为什么使用消息队列?

大多数情况下,使用消息队列目的是::解耦、异步、削峰

通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,彻底解耦了

通过MQ,使得同步的操作变为异步操作,提高效率。

通过MQ,控制服务可以接收到的请求数量

二、消息队列有什么优缺点

优点就是在特殊场景下有其对应的好处,解耦、异步、削峰

缺点有以下几个:

  • 系统可用性降低

系统引入的外部依赖越多,越容易挂掉。需要保证消息队列的高可用

  • 系统复杂度提高,保证消息没有重复消费,怎么处理消息丢失的情况,怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。

  • 一致性问题

A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

三、如何解决消息丢失?

  • ack(消费者确认)(消费者手动ack

  • 持久化 (交换机、队列、消息)

  • 不推荐使用消息事务,会验证降低性能

  • 生产者确认(publisher confirm):生产者发送消息后,等待mq的ACK,如果没有收到或者收到失败信息,则重试。如果收到成功消息则业务结束。

    channel.waitForConfirmsOrDie(10000);
  • 可靠消息服务(可选,自己编写逻辑):对于部分不支持生产者确认的消息队列,可以发送消息前,将消息持久化到数据库,并记录消息状态,后续消息发送、消费等过程都依赖于数据库中消息状态的判断和修改。

四、如何避免消息堆积

  • 通过同一个队列多消费者监听,实现消息的争抢,加快消息消费速度。

五、如何保证消息的有序性?

答:大部分业务对消息的有序性要求不高,如果遇到对时序要求较高的业务,分两种情况来处理:

  • 业务同时对并发要求不高:

    • 保证消息发送时有序同步发送

    • 保证消息发送被同一个队列接收

    • 保证一个队列只有一个消费者,可以有从机(待机状态),实现高可用。

    • 实现主从(Zookeeper集群选主)

  • 业务同时对并发要求较高:

    • 满足上述第一个场景的条件

    • 可以有多个队列

    • 有时序要求的一组消息,通过hash方式分派到一个固定队列 2 hash -> klsdilelksd

六、如何避免消息重复消费?

  • 保证接口幂等即可,那么如何保证接口幂等呢?

    • 某些接口天生幂等,例如查询请求

    • 某些接口天生不幂等,比如新增,还有某些接口的修改功能

      1 - 消息已接收 2- 消息正在处理 3- 已处理完毕

      update set stat =3 where id =2 and stat =2

      • 能根据具体的业务或状态来确定的,在消费端通过业务判断是否执行过

        msgid 转账的短信id=123 - 》 123456 redis msgid -> 123456,userid

 

七、Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

特性ActiveMQRabbitMQRocketMQKafka
单机吞吐量 万级,比 RocketMQ、Kafka 低一个数量级 同 ActiveMQ 10 万级,支撑高吞吐 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响     topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性 ms 级 微秒级,这是 RabbitMQ 的一大特点,延迟最低 ms 级 延迟在 ms 级以内
可用性 高,基于主从架构实现高可用 同 ActiveMQ 非常高,分布式架构 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性 有较低的概率丢失数据 基本不丢 经过参数优化配置,可以做到 0 丢失 同 RocketMQ
功能支持 MQ 领域的功能极其完备 基于 erlang 开发,并发能力很强,性能极好,延时很低 MQ 功能较为完善,还是分布式的,扩展性好 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;

大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。

如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,已经几乎是全世界这个领域的事实性规范。

以上是关于消息队列相关的主要内容,如果未能解决你的问题,请参考以下文章

HOOK相关原理与例子

Linux编程:--消息队列(MessageQueue)相关概念和原理

聊聊消息队列中的基础概念

一文弄懂消息队列相关面试问题:消息可靠性重复消息消息积压利用消息实现分布式事务

消息队列 HTTP下线通告

消息队列技术