1.简介
RocketMQ是阿里巴巴于2012年开源的分布式消息中间件,后来捐赠给Apache软件基金会,并于2017年9月25日称为Apache的顶级项目.作为经历多过多次阿里巴巴双11这种超级工程的洗礼并有稳定出色表现得国产中间件,以其高性能、低延迟和高可靠等特性近年来被越来越多的国内企业所使用
2.模型设计
3.特点
- 具有灵活的可扩展性。RocketMQ天然支持集群,其核心四大组件(NameServer、Broker、Producer、Consumer)的每一个都可以在没有单点故障的情况下进行水平扩展
- 具有海量消息堆积能力。RocketMQ采用零拷贝原理实现了超大量消息的堆积能力,据说单机已经可以支持亿级消息堆积而且在堆积了这么多消息后依然可以保持写入低延迟
- 支持顺序消息。RocketMQ可以保证消息消费者按照消息的发送的顺序对消息进行消费。顺序消息分为全局有序消息和局部有序,一般推荐使用局部有序消息,即生产者通过将某一类的消息按顺序发送到同一个队列中来实现
- 支持多种消息过滤方式。消息过滤分为在服务端过滤和在消费端过滤。在服务端过滤时可以按照消息消费者的要求进行过滤,优点是减少了不必要的消息传输,缺点是增加了消息服务器的负担,实现相对复杂。消费端过滤则完全由具体应用自定义实现,这种方式更加灵活,缺点是很多无用的消息会被传输给消息消费者
- 支持事务消息,RocketMQ除了支持普通消息、顺序消息之外,还支持事务消息,这个特性对于分布式事务来说提供了另一种解决思路
- 支持回溯消费,回溯消费是指对于消费者已经消费成功的消息,由于业务需求需要重新消费,RocketMQ支持按照时间回溯消费时间精确到毫秒,可以向前回溯,也可以向后回溯
4.核心组件
4.1 Topic
主题(Topic)可以被看作是消息的归类,它是消息的第一级类型,比如一个电商系统可以分为交易信息、物流信息等,一条消息必须有一个主题,主题与生产者和消费者的关系非常松散,一个主题可以有0个或多个生产者向其发送消息,一个生产者也可以同时向不同的主题发送消息,一个主题也可以被多个消费者订阅
4.2 Message
消息就是要传输的信息。一条消息必须有一个主题,主题可以被看作是信件要邮寄的地址
一条消息也可以拥有可选的标签和额外的键值对,它们被用于设置一个业务key并在broker上
查找此消息,以便在卡法期间查找问题
4.3 Queue
主题被划分为一个或者多个子主题,即队列(Queue),在一个主题下可以设置多个队列,在发送消息时执行该消息的主题,RocketMQ会轮询该主题下的所有队列将消息发送出去
4.4 Tag
标签(tag)可以被看作是子主题,它是消息的第二级类型,用于伪用户提供额外的灵活性。使用标签,同一业务模块的不同目的的消息就可以用相同的主题而不同的标签来标识。比如交易消息又可以分为交易创建消息,交易完成消息等,一条消息可以没有标签,标签有助于保持代码干净和连贯,并且还可以为RocketMQ的查询系统提供帮助
4.5 Producer
负责生产消息,生产者向消息服务器发送由业务应用程序系统生成的消息,RocketMQ提供了三种方式发送消息,同步、异步、单向
- 同步发送指消息发送方发出数据后,会在收到接收方发出的响应之后才发送下一个数据包,
一般适用于重要通知消息场景,例如重要通知邮件,营销短信等,消息最可靠,如果发送失败,
则进行重传,不会引起消息丢失,但可能会发出重复消息,性能比较低 - 异步发送指发出数据后,不等接收方发回响应,就接着发送下一个数据包
一般适用于可能链路耗时较长而对响应时间敏感的业务场景,例如用户视频上传后通知
转码服务等。一般需要提供回调接口,当broker收到消息时调用回调方法,让Produce回查哪些消息
发送成功,哪些发送失败,对于发送失败的消息,进行重发,对于批量消息而言,如果其中某一个消息发送失败,则需要重发这一批消息,容易引起消息重复,但是这种机制效率最高,实现也比较复杂 - 单向发送指只负责发送消息而不等服务器回应且没有回调函数触发。一般适用于某些耗时
非常短但对可靠性要求并不高的场景,例如日志收集
4.6 Consumer
- 消费者负责消费消息,它从消息服务器拉取消息并将其输入用户应用程序中,
从用户应用的角度来看,消费者由两种类型,拉取型消费者和推送型消费者 - 拉取型消费者(Pull Consumer)主动从消息服务器拉取消息,只要批量拉取到消息,用户应用就会启动消费过程,所以poll被称为主动消费类型
- 推送型消费者(PushConsumer)封装了消息的拉取、消费进度和其他内部维护工作,将消息到达时执行的回调接口留给用户应用程序来实现,所以Push被称为被动消费类型。但从实现上来看,还是从消息服务器拉取消息的,不同于Pull的是,Push首先要注册消费监听器,当监听器触发后才开始消费
4.7 Broker
消息服务器(Broker)是消息存储中心,其主要作用是接收来自生产者的消息并进行存储,消费者从这里拉取消息,它还存储与消息相关的元数据,包括用户组、消费进度偏移量、队列信息等,从部署结构中可以看出,Broker有Master和Slave两种类型,其中Master既可以读又可以写,Slave不可以写只可以读,从物理结构上看,Broker的集群部署有单Master,多Master、多Master多Slave等多种方式
- 单Master
采用这种方式,一旦Broker重启或宕机就会导致整个服务不可用,这种方式风险较大,所以不建议在线上使用 - 多Master
所有消息服务器都是Master,没有Slave.这种方式的优点是配置简单,单个Master当即或重启维护对应用无影响缺点是在单台机器宕机期间,该机器上未被消费的消息在机器恢复之前不可订阅,消息的实时性会受到影响 - 多Master多Slave(同步双写)
为每个Master都配置一个Slave,所以有多对Master-Slave,消息采用同步双写方式,主备都写成功了才返回成功,这种方式的优点是数据与服务没有单点问题,Master宕机时消息五延迟,服务于数据的可用性非常高,缺点是相对异步复制的方式其性能略低,发送消息的延迟略高 - 多Master多Slave(异步复制)
为每个Master都配置一个Slave,所以有多对Master-Slave,消息采用异步复制方式,竹北之间有毫秒级消息延迟,
这种方式的优点时丢失的消息非常少,且消息的实时性不会受到影响,Master宕机后消费者可以继续从Slave消费,中间的过程对用户应用程序透明,不需要人工干预,性能同多Master方式几乎一样,缺点是Master宕机后在磁盘,损坏的情况下会丢失极少量的消息
4.8 Producer Group
生产者组(ProducerGroup)是一类生产者地集合,这类生产者通常发送一类消息并且发送逻辑一致,所以将这些生产者分组在一起,从部署结构上看,生产者通过生产者组的名字来标识自己是一个集群(事务消息回查机制,可以使用到)
4.9 Consumer Group
消费者组(ConsumerGroup)是一类消费者的组合,这类消费者通常消费同一类消息并且消费逻辑一致,所以将这些消费者分组在一起,消费者组于生产者组类似,都是将相同角色的消费者分组在一起并命名的。分组是一个很精妙的概念设计,RocketMQ正是通过这种分组机制,实现了天然的消息负载均衡。消费消息时,通过消费者组实现了将消息分发到多个消费者服务器实例,比如某个主题由9条消息,其中,一个消费者组由3个实例(3个进程或者3台机器),那么每个实例将均摊3条消息,也就意味着我们可以很方便地,通过增加机器来实现水平扩容
4.10 NameServer
名称服务器(NameServer)用来保存Broker相关元信息,并给生产者和消费者查找Broker信息,名称服务器被设计成几乎无状态,可以横向扩展,节点之间无通信,每个NameServer都存储了全部broker的信息,通过部署多台机器来标识自己是一个伪集群,每个Broker在启动时都会到名称服务器中注册,生产者在发送消息前会根据主题到名称服务器中获取Broker的路由信息,消费者,也会定时获取主题的路由信息。所以从功能上看,它应该和Zookeeper差不多,据说RocketMQ的早期版本确实使用了ZooKeeper,后来改为自己实现的名称服务器
5 消费顺序
5.1 顺序消费
顺序消费表示消息消费的顺序同生产者为每个消息队列发送的顺序一致,如果正在处理的全局顺序时强制性的场景,则需要保证所使用的主题只有一个消息队列
5.2 并行消费
不再保证消息顺序,消费的最大并行数量受每个消费者客户端指定的线程池限制