metaq原理简介

1. 前言

本文档旨在描述RocketMQ的多个关键特性的实现原理,并对消息中间件遇到的各种问题进行总结,阐述RocketMQ如何解决这些问题。文中主要引用了JMS规范与CORBA Notification规范,规范为我们设计系统指明了方向,但是仍有不少问题规范没有提及,对于消息中间件又至关重要。RocketMQ并不遵循任何规范,但是参考了各种规范与同类产品的设计思想。

产品发展历史

大约经历了三个主要版本迭代
一、Metaq(Metamorphosis)1.x
由开源社区killme2008维护,开源社区非常活跃。
https://github.com/killme2008/Metamorphosis
二、Metaq 2.x
于2012年10月份上线,在淘宝内部被广泛使用。
三、RocketMQ 3.x
基于公司内部开源共建原则,RocketMQ项目只维护核心功能,且去除了所有其他运行时依赖,核心功能最简化。 每个BU的个性化需求都在RocketMQ项目之上进行深度定制。RocketMQ向其他BU提供的仅仅是Jar包,例如要定制一个Broker,那么只需要依赖rocketmq-broker这个jar包即可,可通过API进行交互,如果定制client,则依赖rocketmq-client这个jar包,对其提供的api进行再封装。开源社区地址:
https://github.com/alibaba/RocketMQ在RocketMQ项目基础上衍生的项目如下

  • com.taobao.metaq v3.0 = RocketMQ + 淘宝个性化需求
    为淘宝应用提供消息服务
  • com.alipay.zpullmsg v1.0 = RocketMQ + 支付宝个性化需求
    为支付宝应用提供消息服务
  • com.alibaba.commonmq v1.0 = Notify + RocketMQ + B2B个性化需求
    为B2B应用提供消息服务

3. 专业术语

  • Producer
    消息生产者,负责产生消息,一般由业务系统负责产生消息。
  • Consumer
    消息消费者,负责消费消息,一般是后台系统负责异步消费。
  • Push Consumer
    Consumer的一种,应用通常向Consumer对象注册一个Listener接口,一旦收到消息,Consumer对象立刻回调Listener接口方法。
  • Pull Consumer
    Consumer的一种,应用通常主动调用Consumer的拉消息方法从Broker拉消息,主动权由应用控制。
  • ProducerGroup
    一类Producer的集合名称,这类Producer通常发送一类消息,且发送逻辑一致。
  • Consumer Group
    一类Consumer的集合名称,这类Consumer通常消费一类消息,且消费逻辑一致。
  • Broker
    消息中转角色,负责存储消息,转发消息,一般也称为Server。 在JMS规范中称为Provider。
  • 广播消费
    一条消息被多个Consumer消费,即使这些Consumer属于同一个Consumer Group,消息也会被Consumer Group中的每个Consumer都消费一次,广播消费中的Consumer Group概念可以认为在消息划分方面无意义。
    在CORBA Notification规范中,消费方式都属于广播消费。
    在JMS规范中,相当于JMS publish/subscribe model
  • 集群消费
    一个Consumer Group中的Consumer实例平均分摊消费消息。例如某个Topic有9条消息,其中一个Consumer Group有3个实例(可能是3个进程,或者3台机器),那么每个实例只消费其中的3条消息。
    在CORBA Notification规范中,无此消费方式。
    在JMS规范中,JMS point-to-point model与之类似,但是RocketMQ的集群消费功能大等于PTP模型。因为RocketMQ单个Consumer Group内的消费者类似于PTP,但是一个Topic/Queue可以被多个Consumer Group消费。
  • 顺序消息
    消费消息的顺序要同发送消息的顺序一致,在RocketMQ中,主要指的是局部顺序,即一类消息为满足顺序性,必须Producer单线程顺序发送,且发送到同一个队列(这就是原理),这样Consumer就可以按照Producer发送的顺序去消费消息。
  • 普通顺序消息
    顺序消息的一种,正常情况下可以保证完全的顺序消息,但是一旦发生通信异常, Broker重启,由于队列总数发生变化,哈希取模后定位的队列会变化,产生短暂的消息顺序不一致。 如果业务能容忍在集群异常情况(如某个Broker宕机或者重启)下,消息短暂的乱序,使用普通顺序方式比较合适。
  • 严格顺序消息
    顺序消息的一种, 无论正常异常情况都能保证顺序,但是牺牲了分布式Failover特性,即Broker集群中只要有一台机器不可用,则整个集群都不可用,服务可用性大大降低。
    如果服务器部署为同步双写模式,此缺陷可通过备机自动切换为主避免,不过仍然会存在几分钟的服务不可用。(依赖同步双写,主备自动切换,自动切换功能目前还未实现)
    目前已知的应用只有数据库binlog同步强依赖严格顺序消息,其他应用绝大部分都可以容忍短暂乱序,推荐使用普通的顺序消息。
  • Message Queue
    在RocketMQ中,所有消息队列都是持久化,长度无限的数据结构,所谓长度无限是指 队列中的每个存储单元都是定长,访问其中的存储单元使用Offset来访问,offset为java long类型,64位,理论上在100年内不会溢出,所以认为是长度无限, 另外队列中 只保存最近几天的数据, 之前的数据会按照过期时间来删除。
    也可以认为Message Queue是一个长度无限的数组,offset就是下标。

4. 消息中间件需要解决哪些问题?

本节阐述消息中间件通常需要解决哪些问题,在解决这些问题当中会遇到什么困难,RocketMQ是否可以解决,规范中如何定义这些问题。

4.1 Publish/Subscribe

发布订阅是消息中间件的最基本功能,也是相对于传统RPC通信而言。在此不再详述。

4.2 Message Priority

规范中描述的优先级是指在一个消息队列中,每条消息都有不同的优先级,一般用整数来描述,优先级高的消息先投递,如果消息完全在一个内存队列中,那么在投递前可以按照优先级排序,令优先级高的先投递。
由于RocketMQ所有消息都是持久化的,所以如果按照优先级来排序,开销会非常大,因此RocketMQ没有特意支持消息优先级,但是可以通过变通的方式实现类似功能, 即单独配置一个优先级高的队列,和一个普通优先级的队列,将不同优先级发送到不同队列即可。
对于优先级问题,可以归纳为2类
1)只要达到优先级目的即可,不是严格意义上的优先级,通常将优先级划分为高、中、低,或者再多几个级别。每个优先级可以用不同的topic表示,发消息时,指定不同的topic来表示优先级,这种方式可以解决绝大部分的优先级问题,但是对业务的优先级精确性做了妥协。
2)严格的优先级,优先级用整数表示,例如0 ~ 65535,这种优先级问题一般使用不同topic解决就非常不合适。如果要让MQ解决此问题,会对MQ的性能造成非常大的影响。这里要确保一点,业务上是否确实需要这种严格的优先级,如果将优先级压缩成几个,对业务的影响有多大?

4.3 Message Order

消息有序指的是一类消息消费时,能按照发送的顺序来消费。例如:一个订单产生了3条消息,分别是订单创建,订单付款,订单完成。消费时,要按照这个顺序消费才能有意义。但是同时订单之间是可以并

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值