消息中间件设计——解耦业务系统与核心系统

消息中间件设计——解耦业务系统与核心系统

同步和异步

什么是同步?什么是异步?

同步与异步指的是消息通信机制

  1. 同步 在发出一个调用后 没有得到的结果之前,该调用不返回,即调用者主动等待这个调用的结果。

  2. 异步 与同步相反,在调用发出后直接返回结果。即在一个异步调用发出后,调用者立刻去做其他事情。

为什么需要消息中间件?

业务系统和核心系统的交互比较频繁,系统之间耦合度太高。核心系统和业务系统有很多重复的开发工作。所以此时需要对它们进行解耦,让各个业务系统能健康的发展。

  1. 什么是消息中间件,有什么作用?
    1. 消息中间件就是一个开发好的系统,可以独立部署,业务系统通过它来发消息和收消息。以达到异步调用的效果。
    2. 消息中间件 可以提升系统性能。
    3. 系统解耦
    4. 大流量消峰
生产级消息中间件的选型?

kafka的优缺点

  1. 支持高吞吐量
  2. 性能较高
  3. 支持集群部署
  4. 有可能丢失数据
  5. 功能比较单一

RabbitMQ的优缺点

  1. 能保证不丢失数据
  2. 能保证高可用
  3. 支持很多高级功能 如重试、死信队列。
  4. 吞吐量比较低
  5. 集群线性扩展比较麻烦
  6. 开发语言是Erlang

RocketMq的优缺点

  1. 吞吐量很高
  2. 能保证高可用、高性能
  3. 保证数据绝对不丢失
  4. 支持大规模集群部署,线性扩展方便
  5. 支持各种高级功能,如延迟消息,消息回溯等
  6. 支持各种高级功能,如延迟消息,消息回溯等
  7. 基于Java语言的开发,能满足 国内绝大部分公司技术栈。
RocketMQ架构原理
  1. NameServer 和bROKER

  2. NameServer是RocketMQ的路由中心,主要提供管理、服务注册及服务发现功能。

  3. Broker是由RocketMQ的核心模块,主要提供消息的接受、存储和拉取等功能

  4. 如何保证高可用?

    1.RocketMQ中的数据是分布式存储在Broker中的,如果右节点宕机,那么RocketMQ是如何保证数据不丢失的呢?

    1. 采用多副本的方式,RocketMQ采用主从架构及多副本策略,来保证Broker数据的高可用
  5. NameServer如何感知Broker的健康状态。

    1. Broker在启动后会自动向所有的NameServer急求你注册,这样所有的NameServer节点都知道了这个Broker。业务系统可以通过Nameserver集群拉取Broker,从而进行消息的发送/获取。
引入消息中间件会带来什么问题?

利用消息中间件能解决系统的各种瓶颈问题,但也会提高系统的复杂度,所以需要解决消息中间件自身的各种问题,这可能会导致降低系统的可用性及稳定性。

RocketMQ的高可用方法

RocketMQ主要采用镜像集群模式来保证高可用,能够百分之百保证数据不丢失。与RabbitMQ的普通集群模式不同,在RabbitMQ的镜像集群模式下,所创建队列queue中的消息及元数据都存在多个RabbitMQ实例上。即在所有的RabbitMQ节点上都有这个queue的完整镜像,在写入消息时会将消息同步到多个mirror queue中。

优点: 在任何一台机器宕机,其他机器还保留了queue的完整消息数据,这样Consumer就可以去其他好的节点上消费信息。

缺点: 性能开销较大,因为消息需要同步到所有节点,所有网络传输消耗很大

kafka的高可用方案

kafka由多个Broker组成,每个Broker就是一个节点。一个Topic可用被划分为多个Partition。Partition可用存在于不同的Broker节点上,每个Partition只存放一部分数据。

如何保证消息不被重复消费?

要完全避免重复消费消息是很难做到的,因为网络的抖动、机器的宕机和处理的异常都是难以避免的。

  1. 生产过程中 可用给每个生产者定义一个唯一的ID
    1. 给生产的每一条消息 定义一个唯一的ID
    2. 消息中间件服务端村消息时,存储生产者ID与最后一条消息ID映射。如果在生产出一条新消息后,消息中间件服务端会先将消息ID与其存储的最后一条消息ID进行对比。如果相等 则是重复消息 。如果不相等,则进行存储。
  2. 消费过程中
    1. 给消息生成一个唯一的ID,在消息消费后将数据ID存到数据库中
    2. 在消费下一条消息前,现在数据库中查询是否有这个消息ID,如果有则是重复消息,不处理。
如何保证消息的顺序性?

在Topic中,一个Partition对应一个Consumer,只能单线程消费。对性能及并发要求稍微高的场景中就很不合适了,因为单线程吞吐量效率太低。

  1. 在消费端程序中写多个内存队列
  2. 将相同key的消息数据放在同一个内存队列中
  3. 在多线程消费时,每个线程对一个内存队列进行消费
消息中间件中的消息延迟?
  1. 监控消息中间件中的消息延迟
  2. 开发消息监控程序
  3. 减少消息中间中的消息延迟
    1. 优化消费代码以提升性能
    2. 增加消费者数量
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容