文章首发于公众号《程序员果果》
地址 : http://blog.itwolfed.com/blog/97

简介

RocketMQ是由阿里捐献给Apache的一款低提早、高并发、高可用、高牢靠的分布式消息中间件。经验了淘宝双十一的洗礼。RocketMQ既可为分布式应用零碎提供异步解耦和削峰填谷的能力,同时也具备互联网利用所需的海量音讯沉积、高吞吐、牢靠重试等个性。

外围概念

  • Topic:音讯主题,一级音讯类型,生产者向其发送音讯。
  • Message:生产者向Topic发送并最终传送给消费者的数据音讯的载体。
  • 音讯属性:生产者能够为音讯定义的属性,蕴含Message Key和Tag。
  • Message Key:音讯的业务标识,由音讯生产者(Producer)设置,惟一标识某个业务逻辑。
  • Message ID:音讯的全局惟一标识,由音讯队列RocketMQ零碎主动生成,惟一标识某条音讯。
  • Tag:音讯标签,二级音讯类型,用来进一步辨别某个Topic下的音讯分类
  • Producer:也称为音讯发布者,负责生产并发送音讯至Topic。
  • Consumer:也称为音讯订阅者,负责从Topic接管并生产音讯。
  • 分区:即Topic Partition,物理上的概念。每个Topic蕴含一个或多个分区。
  • 生产位点:每个Topic会有多个分区,每个分区会统计以后音讯的总条数,这个称为最大位点MaxOffset;分区的起始地位对应的地位叫做起始位点MinOffset。
  • Group:一类生产者或消费者,这类生产者或消费者通常生产或生产同一类音讯,且音讯公布或订阅的逻辑统一。
  • Group ID:Group的标识。
  • 队列:个Topic下会由一到多个队列来存储音讯。
  • Exactly-Once投递语义:Exactly-Once投递语义是指发送到音讯零碎的音讯只能被Consumer解决且仅解决一次,即便Producer重试音讯发送导致某音讯反复投递,该音讯在Consumer也只被生产一次。
  • 集群生产:一个Group ID所标识的所有Consumer均匀摊派生产音讯。例如某个Topic有9条音讯,一个Group ID有3个Consumer实例,那么在集群生产模式下每个实例均匀摊派,只生产其中的3条音讯。
  • 播送生产:一个Group ID所标识的所有Consumer都会各自生产某条音讯一次。例如某个Topic有9条音讯,一个Group ID有3个Consumer实例,那么在播送生产模式下每个实例都会各自生产9条音讯。
  • 定时音讯:Producer将音讯发送到音讯队列RocketMQ服务端,但并不冀望这条音讯立马投递,而是推延到在以后工夫点之后的某一个工夫投递到Consumer进行生产,该音讯即定时音讯。
  • 延时音讯:Producer将音讯发送到音讯队列RocketMQ服务端,但并不冀望这条音讯立马投递,而是提早肯定工夫后才投递到Consumer进行生产,该音讯即延时音讯。
  • 事务音讯:RocketMQ提供相似X/Open XA的散布事务性能,通过音讯队列RocketMQ的事务音讯能达到分布式事务的最终统一。
  • 程序音讯:RocketMQ提供的一种依照程序进行公布和生产的音讯类型,分为全局程序音讯和分区程序音讯。
  • 全局程序音讯:对于指定的一个Topic,所有音讯依照严格的先入先出(FIFO)的程序进行公布和生产。
  • 分区程序音讯:对于指定的一个Topic,所有音讯依据Sharding Key进行区块分区。同一个分区内的音讯依照严格的FIFO程序进行公布和生产。Sharding Key是程序音讯中用来辨别不同分区的关键字段,和一般音讯的Message Key是齐全不同的概念。
  • 音讯沉积:Producer曾经将音讯发送到音讯队列RocketMQ的服务端,但因为Consumer生产能力无限,未能在短时间内将所有音讯正确生产掉,此时在音讯队列RocketMQ的服务端保留着未被生产的音讯,该状态即音讯沉积。
  • 音讯过滤:Consumer能够依据音讯标签(Tag)对音讯进行过滤,确保Consumer最终只接管被过滤后的音讯类型。音讯过滤在音讯队列RocketMQ的服务端实现。
  • 音讯轨迹:在一条音讯从Producer收回到Consumer生产处理过程中,由各个相干节点的工夫、地点等数据汇聚而成的残缺链路信息。通过音讯轨迹,您能清晰定位音讯从Producer收回,经由音讯队列RocketMQ服务端,投递给Consumer的残缺链路,不便定位排查问题。
  • 重置生产位点:以时间轴为坐标,在音讯长久化存储的工夫范畴内(默认3天),从新设置Consumer对已订阅的Topic的生产进度,设置实现后Consumer将接管设定工夫点之后由Producer发送到音讯队列RocketMQ服务端的音讯。
  • 死信队列:死信队列用于解决无奈被失常生产的音讯。当一条音讯首次生产失败,音讯队列RocketMQ会主动进行音讯重试;达到最大重试次数后,若生产仍然失败,则表明Consumer在失常状况下无奈正确地生产该音讯。此时,音讯队列RocketMQ不会立即将音讯抛弃,而是将这条音讯发送到该Consumer对应的非凡队列中。

音讯队列RocketMQ将这种失常状况下无奈被生产的音讯称为死信音讯(Dead-Letter Message),将存储死信音讯的非凡队列称为死信队列(Dead-Letter Queue)。

音讯收发模型

音讯队列RocketMQ反对公布和订阅模型,音讯生产者利用创立Topic并将音讯发送到Topic。消费者利用创立对Topic的订阅以便从其接管音讯。通信能够是一对多(扇出)、多对一(扇入)和多对多。具体通信如下图所示。

  • 生产者集群:用来示意发送音讯利用,一个生产者集群下蕴含多个生产者实例,能够是多台机器,也能够是一台机器的多个过程,或者一个过程的多个生产者对象。

一个生产者集群能够发送多个Topic音讯。发送分布式事务音讯时,如果生产者中途意外宕机,音讯队列RocketMQ服务端会被动回调生产者集群的任意一台机器来确认事务状态。

  • 消费者集群:用来示意生产音讯利用,一个消费者集群下蕴含多个消费者实例,能够是多台机器,也能够是多个过程,或者是一个过程的多个消费者对象。

一个消费者集群下的多个消费者以均摊形式生产音讯。如果设置的是播送形式,那么这个消费者集群下的每个实例都生产全量数据。
一个消费者集群对应一个Group ID,一个Group ID能够订阅多个Topic,如上图中的Group 2所示。Group和Topic的订阅关系能够通过间接在程序中设置即可。

利用场景

  • 削峰填谷:诸如秒杀、抢红包、企业开门红等大型流动时皆会带来较高的流量脉冲,或因没做相应的爱护而导致系统超负荷甚至解体,或因限度太过导致申请大量失败而影响用户体验,音讯队列RocketMQ可提供削峰填谷的服务来解决该问题。
  • 异步解耦:交易系统作为淘宝和天猫主站最外围的零碎,每笔交易订单数据的产生会引起几百个上游业务零碎的关注,包含物流、购物车、积分、流计算剖析等等,整体业务零碎宏大而且简单,音讯队列RocketMQ可实现异步通信和利用解耦,确保主站业务的连续性。
  • 程序收发:细数日常中须要保障程序的利用场景十分多,例如证券交易过程工夫优先准则,交易系统中的订单创立、领取、退款等流程,航班中的旅客登机音讯解决等等。与先进先出FIFO(First In First Out)原理相似,音讯队列RocketMQ提供的程序音讯即保障音讯FIFO。
  • 分布式事务一致性:交易系统、领取红包等场景须要确保数据的最终一致性,大量引入音讯队列RocketMQ的分布式事务,既能够实现零碎之间的解耦,又能够保障最终的数据一致性。
  • 大数据分析:数据在“流动”中产生价值,传统数据分析大多是基于批量计算模型,而无奈做到实时的数据分析,利用阿里云音讯队列RocketMQ与流式计算引擎相结合,能够很不便的实现业务数据的实时剖析。
  • 分布式缓存同步:天猫双11大促,各个分会场目不暇接的商品须要实时感知价格变动,大量并发拜访数据库导致会场页面响应工夫长,集中式缓存因带宽瓶颈,限度了商品变更的拜访流量,通过音讯队列RocketMQ构建分布式缓存,实时告诉商品数据的变动。

下文先以用户注册为场景阐明音讯队列RocketMQ如何实现以下性能:

  • 异步解耦
  • 分布式事务的数据一致性
  • 音讯的程序收发

最初,再以电商的秒杀场景和价格同步场景别离阐明音讯队列RocketMQ所实现的削峰填谷和大规模机器的缓存同步。

异步解耦

传统解决

最常见的一个场景是用户注册后,须要发送注册邮件和短信告诉,以告知用户注册胜利。传统的做法有以下两种:

  • 串行形式

    数据流动如下所述:

    1. 您在注册页面填写账号和明码并提交注册信息,这些注册信息首先会被写入注册零碎。
    2. 注册信息写入注册零碎胜利后,再发送申请至邮件告诉零碎。邮件告诉零碎收到申请后向用户发送邮件告诉。
    3. 邮件告诉零碎接管注册零碎申请后再向上游的短信告诉零碎发送申请。短信告诉零碎收到申请后向用户发送短信告诉。

    以上三个工作全副实现后,才返回注册后果到客户端,用户能力应用账号登录。
    假如每个工作耗时别离为50 ms,则用户须要在注册页面期待总共150 ms能力登录。

  • 并行形式

    数据流动如下所述:

    1. 用户在注册页面填写账号和明码并提交注册信息,这些注册信息首先会被写入注册零碎。
    2. 注册信息写入注册零碎胜利后,再同时发送申请至邮件和短信告诉零碎。邮件和短信告诉零碎收到申请后别离向用户发送邮件和短信告诉。

    以上两个工作全副实现后,才返回注册后果到客户端,用户能力应用账号登录。
    假如每个工作耗时别离为50 ms,其中,邮件和短信告诉并行实现,则用户须要在注册页面期待总共100 ms能力登录。

异步解耦

对于用户来说,注册性能理论只须要注册零碎存储用户的账户信息后,该用户便能够登录,后续的注册短信和邮件不是即时须要关注的步骤。

对于注册零碎而言,发送注册胜利的短信和邮件告诉并不一定要绑定在一起同步实现,所以理论当数据写入注册零碎后,注册零碎就能够把其余的操作放入对应的音讯队列RocketMQ中而后马上返回用户后果,由音讯队列RocketMQ异步地进行这些操作。

数据流动如下所述:

  1. 用户在注册页面填写账号和明码并提交注册信息,这些注册信息首先会被写入注册零碎。
  2. 注册信息写入注册零碎胜利后,再发送音讯至音讯队列RocketMQ。音讯队列RocketMQ会马上返回响应给注册零碎,注册实现。用户可立刻登录。
  3. 上游的邮件和短信告诉零碎订阅音讯队列RocketMQ的此类注册申请音讯,即可向用户发送邮件和短信告诉,实现所有的注册流程。

用户只需在注册页面期待注册数据写入注册零碎和音讯队列RocketMQ的工夫,即期待55 ms即可登录。

异步解耦是音讯队列RocketMQ的次要特点,次要目标是缩小申请响应工夫和解耦。次要的实用场景就是将比拟耗时而且不须要即时(同步)返回后果的操作作为音讯放入音讯队列。同时,因为应用了音讯队列RocketMQ,只有保障音讯格局不变,音讯的发送方和接管方并不需要彼此分割,也不须要受对方的影响,即解耦。

分布式事务的数据一致性

注册零碎注册的流程中,用户入口在网页注册零碎,告诉零碎在邮件系统,两个零碎之间的数据须要放弃最终统一。

一般音讯解决

如上所述,注册零碎和邮件告诉零碎之间通过音讯队列进行异步解决。注册零碎将注册信息写入注册零碎之后,发送一条注册胜利的音讯到音讯队列RocketMQ,邮件告诉零碎订阅音讯队列RocketMQ的注册音讯,做相应的业务解决,发送注册胜利或者失败的邮件。

流程阐明如下:

  1. 注册零碎发动注册。
  2. 注册零碎向音讯队列RocketMQ发送注册音讯胜利与否的音讯。
    2.1. 音讯发送胜利,进入3。

2.2. 音讯发送失败,导致邮件告诉零碎未收到音讯队列RocketMQ发送的注册胜利与否的音讯,而无奈发送邮件,最终邮件告诉零碎和注册零碎之间的状态数据不统一。

  1. 邮件告诉零碎收到音讯队列RocketMQ的注册胜利音讯。
  2. 邮件告诉零碎发送注册胜利邮件给用户。

在这样的状况下,尽管实现了零碎间的解耦,上游零碎不须要关怀上游零碎的业务处理结果;然而数据一致性不好解决,如何保障邮件告诉零碎状态与注册零碎状态的最终统一。

事务音讯解决

此时,须要利用音讯队列RocketMQ所提供的事务音讯来实现零碎间的状态数据一致性。

流程阐明如下:

  1. 注册零碎向音讯队列RocketMQ发送半事务音讯。
    1.1. 半事务音讯发送胜利,进入2。
    1.2. 半事务音讯发送失败,注册零碎不进行注册,流程完结。(最终注册零碎与邮件告诉零碎数据统一)
  2. 注册零碎开始注册。
    2.1. 注册胜利,进入3.1。
    2.2. 注册失败,进入3.2。
  3. 注册零碎向音讯队列RocketMQ发送半音讯状态。
    3.1. 提交半事务音讯,产生注册胜利音讯,进入4。
    3.2. 回滚半事务音讯,未产生注册胜利音讯,流程完结。
    阐明 最终注册零碎与邮件告诉零碎数据统一。
  4. 邮件告诉零碎接管音讯队列RocketMQ的注册胜利音讯。
  5. 邮件告诉零碎发送注册胜利邮件。(最终注册零碎与邮件告诉零碎数据统一)

对于分布式事务音讯的更多具体内容,请参见事务音讯。

音讯的程序收发

音讯队列RocketMQ程序音讯分为两种状况:

  • 全局程序:对于指定的一个Topic,所有音讯将依照严格的先入先出(FIFO)的程序,进行程序公布和程序生产。
  • 分区程序:对于指定的一个Topic,所有音讯依据Sharding Key进行区块分区,同一个分区内的音讯将依照严格的FIFO的程序,进行程序公布和程序生产,能够保障一个音讯被一个过程生产。

在注册场景中,可应用用户ID作为Sharding Key来进行分区,同一个分区下的新建、更新或删除注册信息的音讯必须依照FIFO的程序公布和生产。

削峰填谷

流量削峰也是音讯队列RocketMQ的罕用场景,个别在秒杀或团队抢购流动中应用宽泛。

在秒杀或团队抢购流动中,因为用户申请量较大,导致流量暴增,秒杀的利用在解决如此大量的拜访流量后,上游的告诉零碎无奈承载海量的调用量,甚至会导致系统解体等问题而产生漏告诉的状况。为解决这些问题,可在利用和上游告诉零碎之间退出音讯队列RocketMQ。

秒杀解决流程如下所述:

  1. 用户发动海量秒杀申请到秒杀业务解决零碎。
  2. 秒杀解决零碎依照秒杀解决逻辑将满足秒杀条件的申请发送至音讯队列RocketMQ。
  3. 上游的告诉零碎订阅音讯队列RocketMQ的秒杀相干音讯,再将秒杀胜利的音讯发送到相应用户。
  4. 用户收到秒杀胜利的告诉。

大规模机器的缓存同步

双十一大促时,各个分会场会有玲琅满目标商品,每件商品的价格都会实时变动。应用缓存技术也无奈满足对商品价格的拜访需要,缓存服务器网卡满载。拜访较屡次商品价格查问影响会场页面的关上速度。

此时须要提供一种播送机制,一条音讯原本只能够被集群的一台机器生产,如果应用音讯队列RocketMQ的播送生产模式,那么这条音讯会被所有节点生产一次,相当于把价格信息同步到须要的每台机器上,取代缓存的作用。

零碎部署架构

零碎部署架构如下图所示。

图中所波及到的概念如下所述:

  • Name Server:是一个简直无状态节点,可集群部署,在音讯队列RocketMQ版中提供命名服务,更新和发现Broker服务。
  • Broker:音讯直达角色,负责存储音讯,转发音讯。分为Master Broker和Slave Broker,一个Master Broker能够对应多个Slave Broker,然而一个Slave Broker只能对应一个Master Broker。Broker启动后须要实现一次将本人注册至Name Server的操作;随后每隔30s定期向Name Server上报Topic路由信息。
  • 生产者:与Name Server集群中的其中一个节点(随机)建设长链接(Keep-alive),定期从Name Server读取Topic路由信息,并向提供Topic服务的Master Broker建设长链接,且定时向Master Broker发送心跳。
  • 消费者:与Name Server集群中的其中一个节点(随机)建设长连贯,定期从Name Server拉取Topic路由信息,并向提供Topic服务的Master Broker、Slave Broker建设长连贯,且定时向Master Broker、Slave Broker发送心跳。Consumer既能够从Master Broker订阅音讯,也能够从Slave Broker订阅音讯,订阅规定由Broker配置决定。

参考

本文依据阿里云 RocketMQ产品文档整顿
地址:https://help.aliyun.com/docum...

关注我