消息的发送-RocketMQ知识体系2

上一篇认识了一下RocketMQ,本文讲讲讲RocketMQ生产端的那些事儿,消息的发送相关的原理。

消息发送的流程

RocketMQ 客户端的消息发送可以分为以下三层:

业务层:直接调用 MQ Client 发送 API 的业务代码;

消息处理层:RocketMQ Client 获取业务发送的消息对象后,一系列的参数检查、消息发送准备、参数包装等操作;

通信层:RocketMQ 基于 Netty 封装的一个 RPC 通信服务,RocketMQ 的各个组件之间的通信全部使用这个模块;

**大概的流程:
**

图片

  • Broker启动时,向NameServer注册信息

  • 客户端调用producer发送消息时,会先从NameServer获取该topic的路由信息。消息头code为GET_ROUTEINFO_BY_TOPIC

  • 从NameServer返回的路由信息,包括topic包含的队列列表和broker列表

  • Producer端根据查询策略,选出其中一个队列,用于后续存储消息

  • 每条消息会生成一个唯一id,添加到消息的属性中。属性的key为UNIQ_KEY

  • 对消息做一些特殊处理,比如:超过4M会对消息进行压缩

  • producer向Broker发送rpc请求,将消息保存到broker端。消息头的code为SEND_MESSAGE或SEND_MESSAGE_V2(配置文件设置了特殊标志)

消息的数据结构

消息(Message)

消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。RocketMQ 中每个消息拥有唯一的 Message ID,且可以携带具有业务标识的 Key。系统提供了通过 Message ID 和 Key 查询消息的功能。

图片

核心字段配置

| topic
| 主题名称
| 必填
|
|
| 核心字段 | 作用
| 说明 |

properties
body

其他Message配置

| 字段名 | 默认值 | 说明 |

tags
为每个消息设置tag可做消息过滤
keys
代表这条消息的业务关键词,尽可能保证Key唯一
DelayTimeLevel
消息延时级别,开源RocketMQ支持18个级别的延迟1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

Producer配置

字段名默认值说明
producerGroupDEFAULT_PRODUCERProducer 组名,多个 Producer 如果属于一 个应用,发送同样的消息,则应该将它们 归为同一组
sendMsgTimeout10000发送消息超时时间,单位毫秒
retryAnotherBrokerWhenNotStoreOKfalse如果发送消息返回 sendResult,但是 sendStatus!=SEND_OK,是否重试发送
maxMessageSize131072客户端限制的消息大小,超过报错,同时 服务端也会限制
defaultTopicQueueNums4发送消息时,自动创建服务器不存在的topic默认创建队列数

消息发送方式

Rocketmq提供三种方式可以发送普通消息:同步、异步、和单向发送。

  • 同步:发送方发送消息后,收到服务端响应后才发送下一条消息

  • 异步:发送一条消息后,不等服务端返回就可以继续发送消息或者后续任务处理。发送方通过回调接口接收服务端响应,并处理响应结果。

  • OneWay:发送方发送消息,不等待服务端返回响应且没有回调函数触发,即只发送请求不需要应答。

发送方式对比:发送吞吐量,单向>异步>同步。但单向发送可靠性差存在丢失消息可能,选型根据实际需求确定。

2、消息类型

消息客户端提供多种SDK:普通、顺序、事务、延时消息

Producer负载均衡

producer在发送消息时,默认轮询所有queue,消息就会被发送到不同的queue上。而queue可以分布在不同的broker上。


图片

【关于批量发送】

批量发送消息可提高传递小消息的性能。同时也需要满足以下特征:

  • 批量消息要求必要具有同一topic、相同消息配置

  • 不支持延时消息

  • 建议一个批量消息最好不要超过1MB大小。

实际上RocketMQ在处理批量消息的时候是将其解析为单个消息再发送的,这样就在底层统一了单条消息、批量消息发送的逻辑,让整个框架的设计更加健壮。

生产者高可用

【应用场景】

假如现在有个由三个 broker 节点组成的集群,有 topic1,默认在每个 broker 上创建 4 个队列,分别是:master-a(q0,q1,q2,q3)、master-b(q0,q1,q2,q3)、master-c(q0,q1,q2,q3),上一次发送消息到 master-a 的 q0 队列,此时 master-a 宕机了,如果继续发送 topic1 消息,如果避免再次发送到 master-a?

rocketmq 的解决方案:

发送失败重试和 Broker 故障延迟规避机制。通过配置项 retryTimesWhenSendFailed 来表示同步重试次数,默认为 2 次,加上正常发送 1 次,总共三次机会;选择队列的方式通过 sendLatencyFaultEnable 的值来控制,默认值为 false,不启动 broker 故障延迟机制,值为 true 时启用 broker 故障延迟机制。

(1)发送失败重试

RocketMQ 支持同步、异步发送,无论哪种方法都可以在失败后重试,如果单个 Broker 发生故障,重试会选择其他 Broker 保证消息的正常发送。

失败重试的逻辑:

(2)Broker 规避机制

RocketMQ Client 会维护一个“Broker-发送延迟”关系,根据这个关系选择一个发送延迟级别较低的 Broker,这样能最大限度地利用 Broker 的能力,剔除已经宕机、不可用或发送延迟级别较高的 Broker,尽可能保证消息正常发送。

NameServer挂了怎么办?

如果Namesrv挂了,当新加入的生产消费则获取不到topic路由信息会报MQExecption;如果生产消费缓存了生产者有缓存 Topic 的路由信息,如果NameServer 全部挂掉,并且,此时依然可以发送消息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值