RocketMQ消息中间件

**

RocketMQ

阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,目前主要多用于订单交易系统。
常见的消息中间件产品的比较

**
在这里插入图片描述

RocketMQ简介

有四大块组成
nameServer:相当于注册中心,节点间的nameServer是独立的,存放有服务的borket,nameServer每10秒一次扫描borket连接的状态,如果2分钟没有收到心跳就会断开

borket:是真正存放数据的服务器,单个borket与所有的nameServer保持长链接和心跳(30s/)注册Topic信息到所有Name Server。内部默认有四个队列queue[],是根据队列的索引来区分的

producet:生产者,单个Producer和一台NameServer节点(随机选择)保持长连接,定时查询topic配置信息,如果该NameServer挂掉,生产者会自动连接下一个NameServer,直到有可用连接为止,并能自动重连。与NameServer之间没有心跳。
i:与broker的关系
单个Producer和与其关联的所有broker保持长连接,并维持心跳。默认情况下消息发送采用轮询方式,会均匀发到对应Topic的所有queue中。

consumer,消费者,单个Consumer和一台NameServer保持长连接,定时查询topic配置信息,如果该NameServer挂掉,消费者会自动连接下一个NameServer,直到有可用连接为止,并能自动重连。与NameServer之间没有心跳。

			i:与broker的关系
			单个Consumer和与其关联的所有broker保持长连接,并维持心跳,失去心跳后,则关闭连接,并向该消费者分组的所有消费者发出通知,分组内消费者重新分配队列继续消费。

在这里插入图片描述

RocketMQ概念

RocketMQ架构
RocketMQ作为一款纯java、分布式、队列模型的开源消息中间件,
支持事务消息、顺序消息、批量消息、定时消息、消息回溯等。
RocketMQ由阿里巴巴开源。
在这里插入图片描述

如图所示为RocketMQ基本的部署结构,主要分为NameServer集群、Broker集群、Producer集群和Consumer集群四个部分。
大致流程:

`Broker在启动的时候会去向NameServer注册并且定时发送心跳,Producer在启动的时候会到NameServer上去拉取Topic所属的Broker具体地址,然后向具体的Broker发送消息
为了消除单点故障,增加可靠性或增大吞吐量,可以在多台机器上部署多个nameserver和broker,并且为每个broker部署1个或多个slave`

架构上每个部分的概念


NameServer
NameServer的作用是Broker的注册中心。
每个NameServer节点互相之间是独立的,没有任何信息交互,也就不存在任何的选主或者主从切换之类的问题,因此NameServer是很轻量级的。单个NameServer节点中存储了活跃的Broker列表(包括master和slave),这里活跃的定义是与NameServer保持有心跳。


Topic:一级消息
Topic 与 Tag 都是业务上用来归类的标识,区分在于 Topic 是一级分类,而 Tag 可以理解为是二级分类
是生产者在发送消息和消费者在拉取消息的类别。Topic与生产者和消费者之间的关系非常松散。一个生产者可以发送不同类型Topic的消息。消费者组可以订阅一个或多个主题,只要该组的实例保持其订阅一致即可。
Topic翻译为话题。我们可以理解为第一级消息类型,比如一个电商系统的消息可以分为:交易消息、物流消息等,一条消息必须有一个Topic。


Tag:二级消息
标签,意思就是子主题,为用户提供了额外的灵活性。有了标签,方便RocketMQ提供的查询功能。
可以理解为第二级消息类型,交易创建消息,交易完成消息… 一条消息可以没有Tag


Queue
一个topic下,可以设置多个queue(消息队列),默认4个队列。当我们发送消息时,需要要指定该消息的topic。
RocketMQ会轮询该topic下的所有队列,将消息发送出去。
在 RocketMQ 中,所有消息队列都是持久化,长度无限的数据结构,所谓长度无限是指队列中的每个存储单元都是定长,访问其中的存储单元使用 Offset 来访问,offset 为 java long 类型,64 位,理论上在 100年内不会溢出,所以认为是长度无限。也可以认为 Message Queue 是一个长度无限的数组,Offset 就是下标。


Broker
用来存放消息
Broker是具体提供业务的服务器,单个Broker节点与所有的NameServer节点保持长连接及心跳,定时(每隔30s)注册Topic信息到所有Name Server。Name Server定时(每隔10s)扫描所有存活broker的连接,如果Name Server超过2分钟没有收到心跳,则Name Server断开与Broker的连接。底层的通信和连接都是基于Netty实现的。
负载均衡:Broker上存Topic信息,Topic由多个队列组成,队列会平均分散在多个Broker上,会自动轮询当前所有可发送的broker ,尽量平均分布到所有队列中,最终效果就是所有消息都平均落在每个Broker上
高可用:Broker中分master和slave两种角色,每个master可以对应多个slave,但一个slave只能对应一个master,master和slave通过指定相同的Brokername组成,其中不同的BrokerId==0 是master,非0是slave。
高可靠并发读写服务:master和slave之间的同步方式分为同步双写和异步复制,异步复制方式master和slave之间虽然会存在少量的延迟,但性能较同步双写方式要高出10%左右。
Topic、Broker、queue
在这里插入图片描述



Producer-生产消息
与nameserver的关系
单个Producer和一台NameServer节点(随机选择)保持长连接,定时查询topic配置信息,如果该NameServer挂掉,生产者会自动连接下一个NameServer,直到有可用连接为止,并能自动重连。与NameServer之间没有心跳。
与broker的关系
单个Producer和与其关联的所有broker保持长连接,并维持心跳。默认情况下消息发送采用轮询方式,会均匀发到对应Topic的所有queue中。


Consumer-消费消息
与nameserver的关系
单个Consumer和一台NameServer保持长连接,定时查询topic配置信息,如果该NameServer挂掉,消费者会自动连接下一个NameServer,直到有可用连接为止,并能自动重连。与NameServer之间没有心跳。
与broker的关系
单个Consumer和与其关联的所有broker保持长连接,并维持心跳,失去心跳后,则关闭连接,并向该消费者分组的所有消费者发出通知,分组内消费者重新分配队列继续消费。


groupName
RocketMQ中也有组的概念。代表具有相同角色的生产者组合或消费者组合,称为生产者组或消费者组。
作用是在集群HA的情况下,一个生产者down之后,本地事务回滚后,可以继续联系该组下的另外一个生产者实例,不至于导致业务走不下去。在消费者组中,可以实现消息消费的负载均衡和消息容错目标。
有了GroupName,在集群下,动态扩展容量很方便。只需要在新加的机器中,配置相同的GroupName。启动后,就立即能加入到所在的群组中,参与消息生产或消费。


消费模式

集群模式
在默认情况下,就是集群消费,此时消息发出去后将只有一个消费者能获取消息。
广播模式
广播消费,一条消息被多个Consumer消费。消息会发给Consume Group中的每一个消费者进行消费。

RocketMQ的应用场景
1. 削峰填谷 流量削峰
比如如秒杀等大型活动时会带来较高的流量脉冲,如果没做相应的保护,将导致系统超负荷甚至崩溃。如果因限制太过导致请求大量失败而影响用户体验,可以利用MQ 超高性能的消息处理能力来解决。
2. 异步解耦
通过上、下游业务系统的松耦合设计,比如:交易系统的下游子系统(如积分等)出现不可用甚至宕机,都不会影响到核心交易系统的正常运转。
3. 顺序消息
与FIFO原理类似,MQ提供的顺序消息即保证消息的先进先出,可以应用于交易系统中的订单创建、支付、退款等流程。
4. 分布式事务消息
比如阿里的交易系统、支付红包等场景需要确保数据的最终一致性,需要引入 MQ 的分布式事务,既实现了系统之间的解耦,
又可以保证最终的数据一致性。




RocketMQ集群部署方式

单Mater模式
优点:配置简单,方便部署
缺点:风险较大,一旦Broker重启或者宕机,会导致整个服务不可用
多Master模式
一个集群无 Slave,全是 Master,例如 2 个 Master 或者 3 个 Master
优点:配置简单,单个Master宕机重启对应用没有影响。消息不会丢失
缺点:单台机器宕机期间,这台机器上没有被消费的消息在恢复之前不可订阅,消息实时性会受到影响。

多Master多Slave模式(异步)
每个Master配置一个Slave,采用异步复制方式,主备有短暂消息延迟
优点:因为Master 宕机后,消费者仍然可以从 Slave消费,此过程对应用透明。不需要人工干预。性能同多 Master 模式几乎一样。
缺点:Master宕机后,会丢失少量信息

多Master多Slave模式(同步)
每个Master配置一个Slave,采用同步双写方式,只有主和备都写成功,才返回成功
优点:数据与服务都无单点, Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高
缺点:性能比异步复制模式略低,大约低 10%左右,发送单个消息的 RT会略高。目前主宕机后,备机不能自动切换为主机,后续会支持自动切换功能




** RocketMQ下载与安装**

下载
官方网站下载 ,我们找到 Quick Start 进入快速开始页面找到下载链接

http://rocketmq.apache.org/ 官网下载
http://rocketmq.apache.org/docs/quick-start/ 官网快捷

我们这里使用的是rocketmq-all-4.4.0-bin-release.zip

安装
将下载好的文件解压到D:\coding-software目录下,然后配置环境变量ROCKETMQ_HOME=D:\coding-software\rocketmq-all-4.4.0-bin-release(按照你自己的路径配置)

windows启动操作
启动NAMESERVER
cmd命令框执行进入至‘MQ文件夹\bin’下,然后执行
start mqnamesrv.cmd

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

如果启动失败,应该是因为VM内存不足

打开bin下的runserver.cmd文件

 set "JAVA_OPT=%JAVA_OPT% -server -Xms256m -Xmx256m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"的Xms、Xmx、Xmn改小点

启动BROKER
第一步:修改配置文件

打开bin下的runbroker.cmd文件
 修改大小为:  -Xms512m -Xmx512m -Xmn512m ,如果还不行,数值再小一些
还有就是第37 改为 set "JAVA_OPT=%JAVA_OPT% -XX:MaxDirectMemorySize=512m"
 cmd命令框执行进入至‘MQ文件夹\bin’下,然后执行
start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true
启动BROKER。成功后会弹出提示框,此框勿关闭。

RocketMQ插件部署
RocketMQ插件是一个基于SpringBoot编写的可视化插件,主要用于对RocketMQ提供了可视化的管理界面。
下载
下载地址:https://github.com/apache/rocketmq-externals/releases


SpringBoot整合RocketMQ

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.0.2</version>
</dependency>

消息生成者//\消费者

生产者:rocketMQTemplate.convertAndSend(Topic:tag,生产的消息)
RocketMQ配置生产者和消费者

Topic:tag【一级消息:二级消息】,当时候消费者指定生成者的Topic:tag来监听消息,完成业务
//判断商品上下架状态,发送上架或下架的消息
        String tag=saleable?ITEM_UP_TAGS:ITEM_DOWN_TAGS;
        //基于rocketmq生产上下架消息
        rocketMQTemplate.convertAndSend(ITEM_TOPIC_NAME+":"+tag,spuId);
// rocketMQTemplate.convertAndSend(Topic:tag,生产的消息)

消费者:实现implements RocketMQListener<T> T:泛型表示生成者生产的消息类型
注解:指定消费者的信息,和监听的topic和tag,以及广播模式
//@RocketMQMessageListener(【消费者名称,可以重复】consumerGroup = ITEM_SEARCH_UP,【Topic】topic = ITEM_TOPIC_NAME,
【tag】selectorExpression = ITEM_UP_TAGS,【模式(集群广播)】messageModel = MessageModel.BROADCASTING)

@RocketMQMessageListener(consumerGroup = ITEM_SEARCH_UP,topic = ITEM_TOPIC_NAME,selectorExpression = ITEM_UP_TAGS,
messageModel = MessageModel.BROADCASTING)
public class ItemUpListener implements RocketMQListener<Long> {  // RocketMQListener<T> T:泛型表示生成者生产的消息类型
    @Override
    public void onMessage(Long aLong) {
        
    }
}

======以上我们使用的是广播模式,但这个我们搭建集群的时候,搭建搜索服务和页面展示服务模块集群,那么广播模式下,搜索服务集群内所有监听消息上下架的消费者都会去执行同步索引库的操作,虽然结果没什么影响(索引库保存执行的是覆盖),但对性能是有影响的。
解决方法:我们用集群模式,分别给搜索服务模块,页面服务模块发送消息,那么我们就需要分别发送消息,利用tag的不同来区分来,在哪两个模块去消费消息。

RocketMQ配置生产者和消费者

Topic:tag【一级消息:二级消息】,当时候消费者指定生成者的Topic:tag来监听消息,完成业务
//判断商品上下架状态,发送上架或下架的消息
        
        //基于rocketmq生产上下架消息
        if(saleable){//saleable=true:表示上架
            rocketMQTemplate.convertAndSend(ITEM_TOPIC_NAME+":"+商品上架同步索引库,spuId);
            rocketMQTemplate.convertAndSend(ITEM_TOPIC_NAME+":"+商品上架同步静态页面,spuId);
        }else{
            rocketMQTemplate.convertAndSend(ITEM_TOPIC_NAME+":"+商品下架同步索引库,spuId);
            rocketMQTemplate.convertAndSend(ITEM_TOPIC_NAME+":"+商品下架同步静态页面,spuId);
        }
       
// rocketMQTemplate.convertAndSend(Topic:tag,生产的消息)

消费者:实现implements RocketMQListener<T> T:泛型表示生成者生产的消息类型
注解:指定消费者的信息,和监听的topic和tag,以及广播模式
//@RocketMQMessageListener(【消费者名称,可以重复】consumerGroup = ITEM_SEARCH_UP,【Topic】topic = ITEM_TOPIC_NAME,
【tag】selectorExpression = ITEM_UP_TAGS,【模式(集群广播)】messageModel = MessageModel.BROADCASTING)

商品上架同步索引库========根据tag来区分是同步所以库还是静态页面==========
@RocketMQMessageListener(consumerGroup = ITEM_SEARCH_UP,topic =ITEM_TOPIC_NAME ,selectorExpression = 商品上架同步索引库,
messageModel = MessageModel.BROADCASTING)
public class ItemUpListener implements RocketMQListener<Long> {  // RocketMQListener<T> T:泛型表示生成者生产的消息类型
    @Override
    public void onMessage(Long aLong) {}}
    
商品上架同步静态页面===================
@RocketMQMessageListener(consumerGroup = ITEM_SEARCH_UP,topic =ITEM_TOPIC_NAME ,selectorExpression = 商品上架同步静态页面,
messageModel = MessageModel.BROADCASTING)
public class ItemUpListener implements RocketMQListener<Long> {  // RocketMQListener<T> T:泛型表示生成者生产的消息类型
    @Override
    public void onMessage(Long aLong) {}}    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值