Rocketmq基础(从0开始搭建包括安装,后续更新进阶包括底层核心源码)

RocketMq自理笔记

什么是MQ

消息:是MQ中最小的概念,本质就是一段数据。

队列:在MQ中使用队列的数据结构来存储消息。

MQ是把消息和队列结合起来,称为消息队列(Message Queue),是基础数据结构中“先进先出”的一种数据结构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。

MQ的应用场景

应用解耦

系统的耦合性越高,容错性就越低。以电商应用为例,用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障或者因为升级等原因暂时不可用,都会造成下单操作异常,影响用户使用体验。

流量削峰:

异步解耦方式:

各大MQ产品比较

特性ActiveMQRabbitMQRocketMQKafka
producer-consumer支持支持支持支持
发布-订阅支持支持支持支持
API完备性
多语言支持支持,Java优先语言无关只支持Java支持,Java优先
单机吞吐量万级万级万级十万级
消息延迟微秒级毫秒级毫秒级
可用性高(主从)高(主从)非常高(分布式)非常高(分布式)
消息丢失理论上不会丢失理论上不会丢失
消息重复可控制理论上会有重复
文档完备性
提供快速入门
部署难度
社区活跃度
商业支持阿里云
成熟度成熟成熟成熟成熟(日志领域)
特点功能齐全,大量项目使用借助于erlang语言并发能力,性能高各环节分布式设计,主从HA,支持上万队列,多种消费模式,性能好
支行协议openwire,stomp,rest,xmpp,amqpamqp自定义的一套(社区提供JMS--不成熟)
持久化内存,文件,数据库内存,文件磁盘文件
事务支持支持支持
负载均衡支持支持支持
管理界面一般有web console实现
部署方式独立,嵌入独立独立
评价优点:成熟的产品,已经在很多公司应用但规模不大,各种协议支持较好,有多重语言的客户端;缺点:其重点已放到activemq6.0产品appollo上去了,目前社区不活跃,且对5.x的维护较少;不适用于上千队列场景优点:由于erlang语言的特点,产品性能较好,在互联网公司有较大规模应用,支持amqp协议,有多语言且支持amqp的客户端可用;缺点:erlang语言难度大,集群不支持动态扩展优点:模型简单,接口易用,在阿里大规模应用;性能好,可大量堆积消息在broker中,支持多种消费,包括集群消费,广播消费,开发活跃度高,版本更新快;缺点:没有在mq核心中实现JMS等接口,有些系统要迁移需要修改大量代码;支持的客户端语言不多,目前是java及c++,其中c++不成熟;优点:性能卓越,单机写入TPS约在百万条/秒,最大的优点,就是吞吐量高。在日志领域比较成熟,被多家公司和多个开源项目使用;缺点:Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长;消费失败不支持重试;支持消息顺序,但是一台代理宕机后,就会产生消息乱序;社区更新较慢;

RocketMQ概念术语

  • 消息的发送与消费模型

    image.png

    主题(Topic)

    标识RocketMQ中一类消息的逻辑名字,消息的逻辑管理单位。无论消息生产还是消费,都需要指定Topic。主题主要用于区分消息的种类:一个生产者可以发送消息给一个或者多个Topic,消息的消费者也可以订阅一个或者多个Topic消息。

    消息队列 ( Message Queue )

    简称Queue或Q。消息物理管理单位。一个Topic将有若干个Q。

    无论生产者还是消费者,实际的生产和消费都是针对Q级别。例如Producer发送消息的时候,会预先选择(默认轮询)好该Topic下面的某一条Q发送;Consumer消费的时候也会负载均衡地分配若干个Q,只拉取对应Q的消息。

    生产者(Producer)

    生产者 :也称为消息发布者,负责发送消息至RocketMQ。

    消费者(Consumer)

    消费者 :也称为消息订阅者,负责从RocketMQ接收并消费消息。

    消费者分组(ConsumerGroup)

    标识一类Consumer的集合名称,这类Consumer通常消费一类消息(也称为Consumer Group),且消费逻辑一致。同一个Consumer Group下的各个实例将共同消费topic的消息,起到负载均衡的作用。

    订阅关系(Subscription)

    RocketMQ中的消费者订阅关系(Subscription)是指消费者与主题(Topic)之间的订阅关系。

    消费者可以通过指定订阅规则来订阅某个主题的消息。

    RocketMQ生产消费流程

    image.png

    RockeMQ的安装

    RocketMQ的windows下的安装

    官方下载地址

    https://rocketmq.apache.org/zh/download/

    image.png

    控制台下载

    image.png

    环境要求

    JDK1.8(64位)

    配置环境变量

    变量名:ROCKETMQ_HOME

    变量值:MQ解压路径\MQ文件夹名

    image.png

    启动

    RocketMQ的物理架构中,都是需要先启动NameServer再启动Broker的。所以启动顺序一定不要搞反了。

    启动NAMESERVER

    Cmd命令框执行进入至‘MQ文件夹\bin’下,然后执行‘start mqnamesrv.cmd’,启动NAMESERVER。成功后会弹出提示框,此框勿关闭。

    image.png

    弹出boot success后,说明启动成功,那么NameServer的监听端口是本机是9876端口。

    这种启动方式后,日志的一般放在用户目录下的 logs目录下。

    image.png

    image.png

    启动BROKER

    Cmd命令框执行进入至‘MQ文件夹\bin’下,然后执行

     start mqbroker.cmd -n localhost:9876 

    启动BROKER。成功后会弹出提示框,此框勿关闭。

    image.png

    日志的一般放在用户目录下的 logs目录下。

    image.png

    image.png

    控制台启动

    下载地址:GitHub - apache/rocketmq-dashboard: The state-of-the-art Dashboard of Apache RoccketMQ provides excellent monitoring capability. Various graphs and statistics of events, performance and system information of clients and application is evidently made available to the user.

    控制台端口及服务地址配置:

    下载完成之后,进入‘\rocketmq-console\src\main\resources’文件夹,打开‘application.properties’进行配置。

    image.png

    因为本身控制台也是单独的Java应用,默认的是8080,为了防止与Tomcat冲突,我改成了8089

    image.png

    然后进入dashboard根目录执行‘mvn clean package -Dmaven.test.skip=true’,编译生成。

    image.png

    image.png

    执行‘java -jar rocketmq-dashboard-1.0.0.jar’,启动dashboard。

    image.png

    启动脚本整合

    每次启动RocketMQ的命令还是挺麻烦的,所以这里做了一个脚本整合。

    image.png

    image.png

    因为都是采用默认配置,数据文件的地址默认都是在C盘(C盘最好确保有足够的空间,数据文件默认启动就是1G。)

    image.png

普通消息的发送与消费

三种消息发送方式

同步发送消息

同步发送是指消息发送方发出数据后,同步等待,直到收到接收方发回响应之后才发下一个请求。这种可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知,短信通知。

image.png

异步发送消息

异步消息通常用在对响应时间敏感的业务场景,即发送端不能容忍长时间地等待Broker的响应。消息发送方在发送了一条消息后,不等接收方发回响应,接着进行第二条消息发送。发送方通过回调接口的方式接收服务器响应,并对响应结果进行处理。

image.png

单向发送消息

这种方式主要用在不特别关心发送结果的场景,例如日志发送。单向(Oneway)发送特点为发送方只负责发送消息,不等待服务器回应且没有回调函数触发,即只发送请求不等待应答。此方式发送消息的过程耗时非常短,一般在微秒级别。

image.png

两种消息消费方式

集群消费(负载均衡模式)

消费者采用集群消费方式消费消息,一个分组(Group)下的多个消费者共同消费队列消息,每个消费者处理的消息不同。一个Consumer Group中的各个Consumer实例分摊去消费消息,即一条消息只会投递到一个Consumer Group下面的一个实例。例如某个Topic有3个队列,其中一个Consumer Group 有 3 个实例,那么每个实例只消费其中的1个队列。集群消费模式是消费者默认的消费方式。

image.png

image.png

这里稍微深入一点,就是集群消费提交的偏移量,持久化是存在broker上的。

image.png

image.png

广播消费

广播消费模式中消息将对一个Consumer Group下的各个Consumer实例都投递一遍。即使这些 Consumer属于同一个Consumer Group,消息也会被Consumer Group 中的每个Consumer都消费一次。实际上,是一个消费组下的每个消费者实例都获取到了topic下面的每个Message Queue去拉取消费。所以消息会投递到每个消费者实例。

image.png

image.png

这里稍微深入一点,就是广播消费提交的偏移量,持久化是存在客户端(消费者)的。

image.png

image.png

两种消费监听方式

消息并发监听

image.png

MessageListenerConcurrently:同时开启多个线程并发消费消息。所以这里有可能胡

image.png

对于消费的结果,有两种方式:1、成功,2、重试。

image.png

消费端如果发生消息失败,没有提交成功(或者直接抛出异常、或者返回null值),消息默认情况下会进入重试队列中。

image.png

注意重试队列的名字其实是跟消费群组有关,不是主题,因为一个主题可以有多个群组消费,所以要注意

image.png

重试的间隔默认如下:

image.png

这里重试机制的大体逻辑是这样,消息一旦重试,比如消息A,那么这个消息就会进入%RETRY%....这个队列,然后看是第几次重试,达到了重试间隔,这个消息才会进行消费者重新投递。所以这种情况很容易导致消息的无序。

消息顺序监听

image.png

MessageListenerOrderly:在同一时刻只允许一个线程消费一个队列的消息,并且保证在消费这个队列消息的顺序性。

玩顺序消息时。consume消费消息失败时,不能返回reconsume——later,这样会导致乱序,应该返回suspend_current_queue_a_moment,意思是先等一会(默认1s),一会儿再处理这批消息,而不是放到重试队列里。

image.png

image.png

image.png

image.png

image.png

该消费线程在消费消息时,会使用锁来保证消息的顺序性。当某个消息消费失败时,该消息所属的队列会进入暂停状态,直到该消息处理成功后才会继续消费下一条消息。

严格使用顺序消息注意事项

但是这里有一个误区,不要认为这么做就可以确保顺序消费,因为这个顺序保障只是确保队列级的。消息在不同的队列中依然是无序的。

image.png

所以要做到顺序消费,就必须要创建只能有一个队列的主题。

image.png

同时就算一个主题只有一个队列,你也要使用顺序消费监听,如果使用并发消费监听一样会有问题。

image.png

分区顺序消息

批量消息的发送与消费

image.png

如果发送的消息超过了4M,就需要进行拆分。

image.png

过滤消息

Tag过滤

在大多数情况下,TAG是一个简单而有用的设计,其可以来选择您想要的消息。

image.png

消费者将接收包含TAGA或TAGB或TAGC的消息。但是限制是一个消息只能有一个标签,这对于复杂的场景可能不起作用。在这种情况下,可以使用SQL表达式筛选消息。SQL特性可以通过发送消息时的属性来进行计算。

Sql过滤

需要修改Broker.conf配置文件。加入enablePropertyFilter=true 然后重启Broker服务

image.png

如果抛出错误:说明Sql92功能没有开启

SQL基本语法

RocketMQ定义了一些基本语法来支持这个特性。你也可以很容易地扩展它。

只有使用push模式的消费者才能用使用SQL92标准的sql语句,常用的语句如下:

数值比较: 比如:>,>=,<,<=,BETWEEN,=;

字符比较: 比如:=,<>,IN;

IS NULL 或者IS NOT NULL;

逻辑符号: AND,OR,NOT;

常量支持类型为:

数值,比如:123,3.1415;

字符,比如:'abc',必须用单引号包裹起来;

NULL ,特殊的常量

布尔值,TRUE 或FALSE

消息生产者( 加入消息属性

发送消息时,你能通过putUserProperty来设置消息的属性

image.png

消息消费者 (使用SQL筛选)

用MessageSelector.bySql来使用sql筛选消息

image.png

延时消息

概念介绍

延时消息: Producer 将消息发送到消息队列RocketMQ 服务端,但并不期望这条消息立马投递,而是延迟一定时间后才投递到Consumer 进行消费,该消息即延时消息。

适用场景

消息生产和消费有时间窗口要求:比如在电商交易中超时未支付关闭订单的场景,在订单创建时会发送一条延时消息。这条消息将会在 30 分钟以后投递给消费者,消费者收到此消息后需要判断对应的订单是否已完成支付。如支付未完成,则关闭订单。如已完成支付则忽略。

使用方式

Apache RocketMQ目前只支持固定精度的定时消息,因为如果要支持任意的时间精度,在Broker 层面,必须要做消息排序,如果再涉及到持久化,那么消息排序要不可避免的产生巨大性能开销。(阿里云RocketMQ提供了任意时刻的定时消息功能,Apache的RocketMQ并没有,阿里并没有开源)

发送延时消息时需要设定一个延时时间长度,消息将从当前发送时间点开始延迟固定时间之后才开始投递。

延迟消息是根据延迟队列的level来的,延迟队列默认是

msg.setDelayTimeLevel(3)代表延迟10秒

"1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h"

是这18个等级(秒(s)、分(m)、小时(h)),level为1,表示延迟1秒后消费,level为5表示延迟1分钟后消费,level为18表示延迟2个小时消费。生产消息跟普通的生产消息类似,只需要在消息上设置延迟队列的level即可。消费消息跟普通的消费消息一致。

同时RocketMQ5还支持任意时间的演示

  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值