消息队列RocketMQ基础入门

本文介绍了消息队列在微服务中的重要性,特别是RocketMQ作为常见消息队列中间件的特性。通过案例分析了解消息队列在解耦、异步处理、流量削峰等方面的作用。同时,详细介绍了RocketMQ的架构,包括NameServer、Broker、Producer和Consumer集群,并提供了下载、安装和基础使用示例。
摘要由CSDN通过智能技术生成

一、MQ简介

1、消息队列需求场景

在基于微服务开发的电商项目中,商品的查询和商品的修改是通过两个服务实现的,如果修改了商品的价格,如何保证商品查询服务查询出来的商品价格同步更新呢?

服务与服务之间的通信方式有两种:同步调用和异步消息调用

  • 同步调用:远程过程调用,REST和RPC
  • 异步消息调用:消息队列
    在这里插入图片描述

1)、为了保证数据的一致性,当“商户商品修改服务”在完成对A库中商品信息的修改之后,需要调用“商户商品查询服务”及“自媒体商品查询服务”同步完成B库及C库中商品信息的修改;

2)、如果“商户商品修改服务”使用Ribbon或者Feign同步调用“商户商品查询服务”及“自媒体商品查询服务”虽然能够实现数据的同步修改,但是大大增加了“商户商品修改服务”对用户的响应时间

3)、为了缩短“商户商品修改服务”对用户的响应时间,我们可以在“商户商品修改服务”完成对A库修改之后,通过异步消息队列通知“商户商品查询服务”及“自媒体商品查询服务”。

在这里插入图片描述

2、消息队列概念

MQ全称为Message Queue,消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。

消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。

3、常见消息队列中间件

在这里插入图片描述
RabbitMQ、ActiveMQ、RocketMQ、Kafka

  • RabbitMQ:稳定可靠,数据一致,支持多协议,有消息确认,基于erlang语言
  • Kafka:高吞吐,高性能,快速持久化,无消息确认,无消息遗漏,可能会有有重复消息,依赖于zookeeper,成本高.
  • ActiveMQ:不够灵活轻巧,对队列较多情况支持不好.易于开发
  • RocketMQ:性能好,高吞吐,高可用性,支持大规模分布式,协议支持单一

4、消息队列作用

解耦

场景说明:用户下单后,订单系统需要通知库存系统

传统做法
传统的做法是,订单系统调用库存系统的接口。如下图:
在这里插入图片描述
传统模式的缺点:假如库存系统无法访问,则订单减库存将失败,从而导致订单失败,订单系统与库存系统耦合

如何解决以上问题呢?
使用消息队列
引入应用消息队列后的方案,如下图:
在这里插入图片描述
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功

库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作

在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦

异步

场景说明:用户注册后,需要发注册邮件和注册短信

传统做法
a.串行:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信
在这里插入图片描述
b.并行:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信
在这里插入图片描述
使用消息队列
将不是必须的业务逻辑,异步处理。改造后的架构如下:
在这里插入图片描述

流量削峰

场景说明:商品秒杀业务,一般会因为流量过大,导致流量暴增,应用挂掉

传统做法
限制用户数量

使用消息队列
用户的请求,服务器接收后,首先写入消息队列,秒杀业务根据消息队列中的请求信息,再做后续处理
在这里插入图片描述
假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。

消息通讯

消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等

使用消息队列实现点对点通信
客户端A和客户端B使用同一队列,进行消息通讯
在这里插入图片描述
使用消息队列实现聊天室通信
客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现类似聊天室效果
在这里插入图片描述

日志处理

日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题

使用消息队列完成日志处理

  • 日志采集客户端,负责日志数据采集,定时写受写入Kafka队列
  • Kafka消息队列,负责日志数据的接收,存储和转发
  • 日志处理应用:订阅并消费kafka队列中的日志数据
    在这里插入图片描述

二、Rocket MQ简介

在这里插入图片描述
如图所示为RocketMQ基本的部署结构,主要分为NameServer集群、Broker集群、Producer集群和Consumer集群四个部分。

NameServer集群

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

Broker集群

Broker是具体提供业务的服务器,存储消息内容,单个Broker节点与所有的NameServer节点保持长连接及心跳,并会定时将Topic信息注册到NameServer,其底层的通信和连接都是基于Netty实现的。 Broker中 分master和slave两种角色,每个master可以对应多个slave,但一个slave只能对应一个master, master和slave通过指定相同的Brokername,不同的BrokerId (master为0)成为一个组。master和 slave之间的同步方式分为同步双写和异步复制,异步复制方式master和slave之间虽然会存在少量的延迟,但性能较同步双写方式要高出10%左右。

另外,Broker中还存在一些非常重要的名词需要说明:
Topic和Queue
RocketMQ的Topic/Queue和JMS中的Topic/Queue概念有一定的差异,JMS中所有消费者都会消费一个Topic消息的副本,而Queue中消息只会被一个消费者消费;但到了RocketMQ中Topic只代表普通的消息队列,而Queue是组成Topic的更小单元,集群消费模式下一个消费者只消费该Topic中部分Queue中的消息,当一个消费者开启广播模式时则会消费该Topic下所有Queue中的消息。Topic和 Queue的具体关系可以参考下图

在这里插入图片描述
Tags Tags是Topic下的次级消息类型(注:Tags也支持 TagA || TagB 这样的表达式),可以在同一个Topic下基于Tags进行消息过滤。Tags的过滤需要经过两次比对,首先会在Broker端通过Tag hashcode进行一次比对过滤,匹配成功传到consumer端后再对具体Tags进行比对,以防止Tag hashcode重复的情况。Queue中具体的存储单元结构如下图:
在这里插入图片描述

Producer集群

与nameserver的关系
单个Producer和一台nameserver保持长连接,定时查询topic配置信息,如果该nameserver挂掉,生产者会自动连接下一个nameserver,直到有可用连接为止,并能自动重连。与nameserver之间没有心跳。

与broker的关系
单个Producer和与其关联的所有broker保持长连接,并维持心跳。默认情况下消息发送采用轮询方式,会均匀发到对应Topic的所有queue中。

最佳实践
1)、一个应用尽可能只使用一个 Topic,消息子类型用 tags 来标识,tags 可以由应用自由设置。只有发送消息设置了tags,消费方在订阅消息时,才可以利用 tags 在 broker 做消息过滤。

2)、每个消息在业务层面的唯一标识码,要设置到 keys 字段,方便将来定位消息丢失问题。服务器会为每个消息创建索引(哈希索引),应用可以通过 Topic,key 来查询返条消息内容,以及消息被谁消费。由于是哈希索引,请务必保证 key 尽可能唯一,这样可以避免潜在的哈希冲突。

3)、消息发送成功或者失败,要打印消息日志,务必要打印 sendresult 和 key 字段。

4)、对于消息不可丢失应用,务必要有消息重发机制。例如:消息发送失败,存储到数据库,能有定时程序尝试重发或者人工触发重发。

5)、某些应用如果不关注消息是否发送成功,请直接使用sendOneWay方法发送消息。

Consumer集群

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

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

最佳实践
1)、Consumer 数量要小于等于queue的总数量,由于Topic下的queue会被相对均匀的分配给Consumer,如果 Consumer 超过queue的数量,那多余的 Consumer 将没有queue可以消费消息。

2)、消费过程要做到幂等(即消费端去重),RocketMQ为了保证性能并不支持严格的消息去重。

3)、尽量使用批量方式消费,Rocket

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值