RocketMQ调研笔记

RocketMQ调研笔记

毫无疑问,RocketMQ是目前最受欢迎的消息中间件之一,由淘宝中间件团队研发,目前已经普遍应用于淘宝,天猫,蚂蚁金服,口碑等各式各样的复杂业务。缓存

为何选择RocketMQ?

  • 消息不丢失【重点】
  • 稳定性高,吞吐量高,性能好
  • 强大的技术团队,健壮的社区力量
  • 架构主轻量,组件无状态
  • 采用Java语言编写,技术体系上更加契合

概念

Producer架构

消息生产者。生产者将业务应用系统产生的消息投递到Broker机器上,投递方式有同步,异步,单向等。并发

Producer Group:负载均衡

消息生产者组。多个相同的生产者事例集群为一组。同一个生产者组的不一样生产者实例能够被Broker处理以提交或者回滚(事务保证)。生产者组只容许一个实例存在,即不支持生产者组的集群处理。异步

Consumer性能

从Broker集群上拉取消息进行处理。而且提供了两种模型:线程

  • 拉模型,consumer集群主动从broker拉去数据
  • 推模型,在拉模型的基础上进行处理

Consumer Group架构设计

消息者组,支持负载均衡,容错系统。消费者组的消费者实例必须具备彻底相同的topic订阅。设计

Topiccode

topic是producer与consumer投递消息与拉取消息的区分点,可是topic与producer与consumer之间的关系很是松散。具体而言,一个topic可能有零个,一个或多个向其发送消息的producer; 相反,producer能够发送不一样topic的信息。从consumer的角度来看,一个subject可能由零个,一个或多个consumer群体订阅。一样,一个consumer群体能够订阅一个或多个topic,只要这个群体的实例保持其订阅的一致性。

Broker

它接收producer发送的消息,存储消息并准备处理来自consumer的请求(consumer拉模型)。它还存储消息相关的元数据,包括消费者组,消费进度偏移和topic队列信息。

Name Server

用来保存topic的路由信息。

  • NameServer用来保存活跃的broker列表,包括Master和Slave。
  • NameServer用来保存全部topic和该topic全部队列的列表。
  • NameServer用来保存全部broker的Filter列表。

消息模型

集群、广播

消息顺序

有序:费消息有序意味着消息被消费者按照消息队列发送的顺序进行消费。若是您正在处理强制使用全局顺序的状况,请确保您使用的topic只有一个消息队列。警告:若是指定消耗有序,则消费消息的最大并发度是消费者组订阅的消息队列的数量。 无序:同时使用消息时,消息消息的最大并发性仅受限于为每一个客户端指定的线程池。警告:在此模式下再也不保证消息顺序。

RocketMQ架构设计

架构上分为四个部分,由producer,consumer,namesrv以及broker组成。

rocketmq架构图.png

生产者

SendStatus,包含于SendResult中,表示消息的投递状态

  • FLUSH_DISK_TIMEOUT:表示若是Broker配置了FlushDiskType(刷盘策略)为SYNC_FLUSH(同步刷盘),而且Broker在默认时间(syncFlushTimeout刷盘超时时间)内没有完成刷新磁盘则返回该状态。
  • FLUSH_SLAVE_TIMEOUT:表示若是Broker配置了SYNC_MASTER,没有在默认时间(syncFlushTimeout刷盘超时时间)内与主Broker完成同步,则返回该状态。
  • SLAVE_NOT_AVAILABLE:表示Broker配置了SYNC_MASTER,可是没有配置从库,则返回该状态。
  • SEND_OK:表示成功。可是它不表明这可靠,为了确保不会丢失任何消息,您还应该启用SYNC_MASTER或SYNC_FLUSH(指刷盘策略)。

Duplication or Missing

若是投递消息失败,返回状态为:FLUSH_DISK_TIMEOUT 或者 FLUSH_SLAVE_TIMEOUT

  • 若是选择继续执行程序,则消息丢失。
  • 不然选择重发该消息,可是可能会致使消息重复。建议重发,由于能够经过其余手段来规避消息重复消费问题。

producer工做机制

producer按期从namesrv获取可用的topic路由信息,包括可用的broker列表,并缓存在本地。producer发送消息时经过轮训的方式从namesrv上拉取的路由信息中选择一个可用的broker,根据某种策略把消息发送到该broker。若是namesrv挂掉,producer就使用本地的topic路由信息,若是此时producer重启了,那就没有topic路由信息了,也就没法发送消息。

消费者

Consumer Group and Subscriptions

不一样的Consumer Group能够独立消费相同的topic,而且在消费失败以后均可以有各自的消费补偿(重试机制)。 请确保同一个Consumer Group中的每一个consumer实例订阅相同的topic。

MessageListener

  • Orderly 能够保证消息顺序地被消费,由于它会将锁住每个消息队列并依次消费。若是不是对顺序消息有极强的要求,不建议使用。异常请使用ConsumeConcurrentlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT
  • Concurrently 不保证消息的顺序问题,consumer同时拉取消息并消费。异常请使用:ConsumeConcurrentlyStatus.RECONSUME_LATER

ConsumeFromWhere 若是新建一个consumer group ,须要确认是否消费broker保存的历史数据

  • CONSUME_FROM_LAST_OFFSET将忽略历史消息,并消耗以后产生的任何东西。
  • CONSUME_FROM_FIRST_OFFSET将消耗Broker中存在的全部消息。
  • CONSUME_FROM_TIMESTAMP消费在指定的时间戳以后产生的消息。

Duplication 重复消费

建议经过业务上的其余手段来保证消息的不重复消费,由于在消息队列在消费体系中有很是多的状况会出现消息重复消费的问题。

服务注册与发现

服务注册与发现是一个无状态的组件,即namesrv与namesrv相互隔离,没有心跳检查,没有主从复制,没有主从选举等问题。

broker

brokerRole

  • ASYNC_MASTER
  • SYNC_MASTER
  • SLAVE

若是用户没法容忍消息丢失,那么建议用户部署一个同步主库并配上一个从库来处理。若是用户能够容忍消息缺失可是必定要保证Broker的高可用状态,那么建议用户部署一个异步主库配置一个从库来处理。若是用户只想要简单上手使用(不谈高可用,零容错等问题),建议用户只须要配置一个异步主库便可处理。

FlushDiskType

  • ASYNC_FLUSH
  • SYNC_FLUSH

推荐使用ASYNC_FLUSH,由于SYNC_FLUSH代价昂贵,会形成太多的性能损失。若是你想要可靠性,咱们建议你使用SYNC_MASTERSLAVE

broker工做机制

broker负责存储消息,存储队列信息,维护消费进度,定时向namesrv上报topic路由信息。若是一台broker挂掉,那producer不会立刻感知到,namesrv也不会当即把这个broker从它维护的可用broker列表摘除,而是要等到broker心跳超时后才会摘除。摘除后,producer下次从namesrv获取最新的可用的broker列表时,才会发现此broker不存在了,而后也就不会再发送消息到此broker。在此以前broker挂掉的这段时间内,producer仍是会发消息到这个已经挂掉的broker的,可是producer内部有重试机制,若是发送到某个broker失败几回,那就会选择其余可用broker来发送。因此,对于用户而言,最终发送消息都是成功的。brokernamesrv的心跳超时时间,以及producernamesrv定时拉取topic路由信息的时间,均可配置。

弊端

  • 主从复制不支持master选举,master宕机后消息服务近乎不可用(slave可继续消费旧的消息)
  • 没法作到真正意义上的读写分离,只有当master消费性能过低时(由RocketMQ决定)才会将读请求分摊到slave
  • 主从数据不一致,有可能形成数据重复消费
相关文章
相关标签/搜索