【专栏RocketMq】简单介绍

分布式系统的无状态和有状态详解

状态服务于无状态服务比较:

  • 无状态服务(stateless service)对单次请求的处理,不依赖其他请求,也就是说,处理一次请求所需的全部信息,要么都包含在这个请求里,要么可以从外部获取到(比如说数据库),服务器本身不存储任何信息
  • 有状态服务(stateful service)则相反,它会在自身保存一些数据,先后的请求是有关联的

为什么会有俩者的产生?

  • 单体条件下面,服务只有一个,因此状态每个时刻也就只有一种状态。在分布式集群环境下面,就存在一个状态同步问题,因此也有有状态服务设计和无状态服务设计。比如session,如果session保存在每一台服务器上,那么就是有状态设计,可能会出现集群内,服务状态不一致的现象;如果session由专门的一台服务器来保存,就是无状态设计,服务不保存状态,需要的时候从同一的服务器中获取,保证了服务在任何时刻的状态一致。
  • 有状态的服务,会有比较明显的缺点,服务间数据需要同步,成为副本关系,逻辑复杂也浪费资源 ;无状态的应用服务器,不保存上下文信息,只负责对用户的每次请求提交数据进行处理然后返回处理结果
    无状态应用服务器之间是对等的关系,无依赖,请求到哪个服务器,处理结果都一样的。

为什么使用MQ?优点?常用场景?

解耦:

  • A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?A 系统负责人几乎崩溃…A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系统都需要 A
    系统将这个数据发送过来。如果使用 MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ
    里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A
    系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。
    就是一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用
    MQ 给它异步化解耦。

异步:

  • A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近
    1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求。如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ
    队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms。

削峰:

  • 减少高峰时期对服务器压力

Rocketmq组件介绍

角色作用
Nameserver轻量级注册中心,无状态;这也是和zookeeper的重要区别之一。zookeeper是有状态的。
Producer消息生产者,负责发消息到Broker。
Broker就是MQ本身,负责收发消息、持久化消息等。
Consumer消息消费者,负责从Broker上拉取消息进行消费,消费完进行ack。

Rocketmq负载均衡

producer端

  • 发送端指定 message queue发送消息到相应的 broker,来达到写入时的负载均衡 提升写入吞吐量,当多个producer同时向一个 broker 写入数据的时候,性能会下降 消息分布在多 broker 中,为负载消费做准备
    默认策略是随机选择: producer 维护一个 index 每次取节点会自增 index 向所有 broker 个数取余 自带容错策略

consumer端

  • 采用的是平均分配算法来进行负载均衡。 他负载均衡算法 平均分配策略(默认)(AllocateMessageQueueAveragely) 环形分配策略(AllocateMessageQueueAveragelyByCircle)
    手动配置分配策略(AllocateMessageQueueByConfig)
    机房分配策略(AllocateMessageQueueByMachineRoom)
    一致性哈希分配策略(AllocateMessageQueueConsistentHash)
    靠近机房策略(AllocateMachineRoomNearby)

Rocketmq保证消息不丢失

Producer端如何保证消息不丢失

采取send()同步发消息,发送结果是同步感知的。

发送失败后可以重试,设置重试次数。默认3次。

producer.setRetryTimesWhenSendFailed(10);

集群部署,比如发送失败了的原因可能是当前Broker宕机了,重试的时候会发送到其他Broker上。

Broker端如何保证消息不丢失

修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。

flushDiskType = SYNC_FLUSH

集群部署,主从模式,高可用。

Consumer端如何保证消息不丢失

完全消费正常后在进行手动ack确认。

Rocketmq分布式事务

分布式系统中的事务可以使用TCC(Try、Confirm、Cancel)、2pc来解决分布式系统中的消息原子性

RocketMQ 4.3+ 提供分布事务功能,通过 RocketMQ 事务消息能达到分布式事务的最终一致

RocketMQ实现方式:

Half Message:
预处理消息,当broker收到此类消息后,会存储到RMQ_SYS_TRANS_HALF_TOPIC的消息消费队列中

检查事务状态:
Broker会开启一个定时任务,消费RMQ_SYS_TRANS_HALF_TOPIC队列中的消息,每次执行任务会向消息发送者确认事务执行状态(提交、回滚、未知),如果是未知,Broker会定时去回调在重新检查。

超时: 如果超过回查次数,默认回滚消息。

也就是他并未真正进入Topic的queue,而是用了临时queue来放所谓的half message,等提交事务后才会真正的将half
message转移到topic下的queue。

Rocketmq保证消息幂等

方式有很多一般可以通过redis锁+数据库查询是否更新 或者通过数据库唯一标识实现 或者通过发送者和消费者约定的唯一业务id看是否消费过
存入redis如果感觉不保险可以入库

Rocketmq消息刷盘策略

同步刷盘:消息被写入PageCache后立即刷盘,只有当消息被持久化到磁盘后才会响应ACK。

异步刷盘:消息在被写入PageCache后就会响应ACK,当PageCache里的消息积累到一定量后,由OS线程将PageCache里的消息刷入磁盘。注:如果RocketMQ服务挂了,PageCache里的消息并不会丢失,因为PageCache是属于Linux系统的缓冲区,只有当服务器突然断电才会导致消息丢失。

异步刷盘+缓冲区:RocketMQ将一部分内存当做缓冲区,消息被写入内存缓冲区后就返回ACK,由后台程序将内存缓冲区里的消息刷入磁盘。注:在该模式下,RocketMQ服务宕机或服务器突然断电都会导致消息丢失。

即将完善部分…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

抵制平庸 拥抱变化

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值