Rocketmq
2021-11-03 18:13:07 7 举报
AI智能生成
MQ,消息中间件技术选型,技术核心原理整理
作者其他创作
大纲/内容
压力测试
JVM参数设置
配置启动mq脚本
linux os内核参数设置
vm.overcommit_memory
0
中间件系统申请内存,os内核会检查可用内存是否足够,如果足够则分配内存,如果觉得剩余内存不够,则内存申请失败,导致中间件系统异常报错
1
一般为1,表示把所有可用物力内存都允许分配给中间件,避免内存申请失败造成中间件报错
子主题
2
vm.max_map_count
默认65536,这个参数影响中间件开启线程数,建议扩大10倍,如655360
vm.swappiness
0
尽量不把任何进程放到磁盘swap区域去,尽力使用物理内存
60
默认值,有点偏高,可能导致中间件运行不活跃的时候贝博腾出内存空间然后放入磁盘swap区域去
100
尽量把一些进程放到磁盘swap区域去,内存腾出来给活跃的进程使用
10
生成这个参数尽量调小,尽量使用武力内存,别放在磁盘swap区域
ulimit
默认1024,控制linux的最大文件链接数
RocketMQ核心参数设置
RocketMQ发送消息线程数:sendMessageThreadPollNums=16,默认16
压测关注点
RockerMQ消息延迟和TPS
CPU负载情况
内存使用率
JVM GC频率
磁盘IO负载
网卡流量
压测方法
采用多台机器开启大量线程并发读写消息
为什么要使用mq
下单核心流程环境太多,性能差
下单支付流程
订单系统
积分系统
增加积分
仓储系统
通知发货
库存系统
扣减库存
第三方短信系统
发Push推送
促销系统
发送优惠券,红包
更新订单状态
问题
核心链路过长,同步长达好几秒
改进
将订单支付信息放入mq,然后由其他系统从mq调用消费
订单退款的流程可能面临退款失败的风险
关闭过期订单的时候,存在扫描大量订单数据问题
和第三方物流系统耦合在一起,性能存在抖动的风险
大数据团队要获取订单数据,存在不规范直接查询订单数据库的问题
解决
订单系统发送binlog日志到rocketmq中由大数据自己去同步数据
做秒杀活动订单数据库压力过大
库存提前放入redis扣减库存
页面静态化
多级缓存
CDN
redis
Nginx
独立出秒杀订单系统
防止对正常下单用产生影响
基于zk通知nginx拦截订单完成后的无效请求
问答题防止刷单
瞬间高并发下单请求放入mq削峰
ActiveMQ
几年前的技术,目前很少有公司用,不考虑
RabbitMQ
优势
高可用,支持集群部署,部分宕机不影响其他机器使用
数据不丢失
官方文档详细全面
社区活跃
劣势
低吞吐,每秒几万QPS
集群扩展麻烦
开发语言为erlang,国内少有精通erlang语言工程师,无法阅读源代码修改其源码
适用范围:中小型公司,无高并发场景,无修改源码需求
Kafaka
优势
高吞吐,每秒几十万QPS
高可用,支持集群部署,部分宕机不影响其他机器使用
低延迟,发送消息都是毫秒级
官方文档详细全面
社区活跃
分布式存储
劣势
数据丢失,kafka解释消息写入磁盘缓存区,不会写入硬盘,机器宕机会导致磁盘缓冲区数据直接丢失
功能过于简单
如果实现数据0丢失导致吐吞量急剧下降
适用场景
大数据领域的日志传输,高吞吐,允许数据丢失
RocketMQ
优势
高吞吐,每秒几十万QPS
高可用,支持集群部署,部分宕机不影响其他机器使用
功能齐全。支持延迟消息,事务消息,消息回溯,死信队列,消息积压
java语言开发,符合大多数公司技术栈
社区活跃
分布式存储
劣势
官网文档相对简单
适用场景
大中小型公司
消费消息
负载均衡模式
mq发送的每一条消息只会给一个消费者消费
默认
广播模式
mq发送的每一条消息每个消费者都会消费
consumer.setMessageModel(MessageModel.BROADCASTING)
消息发送
同步发送消息
SendResult sendResult = producer.send(msg);
等待mq返回结果SendResult
异步发送消息
producer.sentRetryTimesWhenSendAsyncFailed(0);
设置异步发送失败重试次数为0
不用等待mq返回结果,继续向下执行
发送消息改造
单向发送消息
生产者发送消息
基于Topic
每个Topic分布式存储在Broker中
MessageQueue
消息存储在MessageQueue
Topic必须指定MessageQueue
MEssageQueue存在于Topic
刷盘策略
同步刷盘
强制写入磁盘才ACK
优点
数据不丢失
缺点
写入吞吐量下降
异步刷盘
写入OS cache直接ACK
优点
高吞吐写入
缺点
丢失数据风险
写入方式
每个Topic对应多个Brock,每个Brock有多个MessageQueue,基于MessageQueue的CommitLog顺序写入
集群方式
多Master多Slave
同步方式
Slave自己pullMaster获取消息
消费者消费消息
可能从Master Broker消费,也可能从Slave Broker消费
由Master Broker建议决定
改进
基于Dledger实现RocketMQ高可用自动切换
RocketMQ4.5后改进
Master Broker宕机
通过Dledger技术和Raft协议算法进行lead选举
自动选举Slave为新的Master Broker
RocketMQ集群部署
机器
NameServer
3台机器,每台8核CPU+16G内存+500G磁盘+千兆网卡
Broker
3台机器,每台24核+48G内存+1TB磁盘+千兆网卡
生产者
2台机器,每台4核+8G+500GB+千兆网卡
消费者
2台机器,每台4核+8G+500GB+千兆网卡
部署
1. 安装jdk,配置Java_HOME
2. 构建Dledger
集群方式
NameServer
NameServer
NameServer
Master
Slave
Slave
Master
Slave
Slave
监控
rocketmq-console
部署
Linux
在三台NameServer的任意一台部署即可
1. git clone https://github.com/apache/rocketmq-externals.git
2. cd rocketmq-externals/rocketmq-console
3. mvn package -DskipTests
4. 进入targert目录
jar -jar rocketmq-console-ng-1.0.1.jar--server.port=8080 --rocketmq.config.namesrvAddr=127.0.0.1:9876
Windows
1. 在github下载
2. 修改配置文件
rescouse
rocketmq.config.namesrvAddr=
3. 打包
4. 上传到Linux
springboot项目
DLedger
Ralf选举策略
开始各个Broker都投选自己,发送投票给其他Broker
第一轮选举失败,各个Broker休眠随机数
最先醒来的Broker投票给自己发送投票新给其他Broker,其他Broker后醒来,也投给最先醒来的Broker,
只要有(3台机器 / 2) + 1个人投票给某个人,就会选举他当Leader,这个(机器数量 / 2) + 1就是大多数的意思。
只要有(3台机器 / 2) + 1个人投票给某个人,就会选举他当Leader,这个(机器数量 / 2) + 1就是大多数的意思。
Raft协议进行多副本同步
两阶段提交
uncommitted
leed Broker接受消息后标记为uncommit
commited
1. 基于DLedgerServer组件把这个uncommitted数据发送给Follower Broker的DLedgerServer
2. 接受消息的 Follower Broker必须返回ack给Leader Broker的DLedgerServer
3. 收到超过半数的Follower Broker返回ack之后,就会将消息标记为committed状态
Follower 由于网络波动未接受到Master消息
commit index的位置下次在发送数据过去的时候会把就数据带上这部分数据slave接受到后根据自己当前的index来判断这部分消息是否存在不存在则会保存
消费模式
集群消费模式
消费组仅一个实例获取消息
默认集群消费模式
广播消费模式
消费者每个实例都获取消息
修改
consumer.setMessageModel(MessageModel.BROADCASTING);
消息零丢失方案
生产者保证100%投递消息到mq
生产者发送half事务出去
失败
1. MQ 接受到消息因网络延迟导致
1.回滚所有操作
2. MQ重启后发现half长时间未commit会自动回调接口,然后执行rollback
2. MQ挂了
回滚所有操作
成功代表消息已写入MQ内部
执行回调接口
回调接口执行成功
提交commit到MQ
回调接口执行失败
Raft协议主从同步+同步刷盘
消费者保证100%消费
不能异步消费
整体架构
多主多从+同步刷盘
事务消息功能
作用
保证消息一定会被写入到mq中
原理分析
订单支付成功通知
发送half(订单支付成功)到mq
等待mq返回响应half消息
失败
更新订单状态为关闭
通知支付系统退款
half因网络原因写入mq,订单系统回调发送rollback给mq删除half
成功
更新订单状态为已支付
更新失败
发送rollback给mq删除half
更新订单状态为关闭
通知支付系统退款
更新成功
发送commit请求给MQ
其他系统对half消息可见
失败
再次commit请求
成功
事务+重试
缺点
订单接口性能下降
Redis、Elasticsearch数据无法回滚
消息幂等性
生产者
去MQ查询是否发送过消息
将发送的订单消息写入Redis
问题
可能发送消息后Redis宕机引发重复发送
顺序消费
保证童一个订单进入童一个Queue
保证一个Queue只能被一个Consumer消费
代码实现
生产者
消费者
消息过滤
Tag
0 条评论
下一页