《RocketMQ实战与原理解析》学习笔记1

分布式消息队列的功能

  • 应用解耦
    在这里插入图片描述
  • 流量消峰

应用系统流量瞬间猛增,这个时候如果没有缓冲机制,不可能承受住短时大流 量的冲击。通过利用消息队列,把大量的请求暂存起来,分散到相对长的一段时间内 处理,能大大提高系统的稳定性和用户体验 。

  • 消息分发
    在这里插入图片描述
  • 保持最终一致性
  • 方便动态扩容

RocketMQ

RocketMQ四个角色
  • Producer
  • Consumer
  • Broker
  • NameServer

启动 RocketMQ 的顺序是先启动 NameServer,再启动 Broker,这时候消息队列已经可以提供服务了,想发送消息就使用 Producer来发送,想接收消息就使用Consumer来接收 。
很多应用程序既要发送,又要接收,可以启动多个Producer 和 Consumer 来发送多种消息,同时接收多种消息 。
为了消除单点故障,增加可靠性或增大吞吐量 ,可以在多台机器上部署多个NameServer 和Broker,为每个Broker部署一个或多个 Slave。

在这里插入图片描述

生产者和消费者

根据使用者对读取操作的控制情况,消费者分为两种类型:

  • DefaultMQPushConsumer : 由系统控制读取操作,收到消息后自动调用传入的处理方法来处理;
  • DefaultMQPullConsumer : 读取操作中的大部分功能由使用者自主控制 。
DefaultMQPushConsumer

在这里插入图片描述
DefaultMQPushConsumer需要设置三个参数:

  1. Consumer的GroupName
    Consumer的GroupName用于把多个Consumer组织到一起,提高并发处理能力,GroupName需要和消息模式(MessageModel)配合使用。

RocketMQ支持两种消息模式:Clustering和Broadcasting。
Clustering:同一个ConsumerGroup(GroupName相同)里的每个consumer只消费所订阅消息的一部分内容,同一个ConsumerGroup里所有的Consumer消费的内容合起来才是所订阅Topic内容的整体,从而达到负载均衡的目的。
Broadcasting:同一个ConsumerGroup里的每个Consumer都能消费到所订阅Topic的全部消息,也就是一个消息会被多次分发,被多个Consumer消费。

  1. NameServer的地址和端口号
    可以填写多个,用分号隔开,达到消除单点故障的目的
  2. Topic的名称
    用来标识消息类型,需要提前创建。

如果不需要消费某个Topic下的所有消息,可以通过指定消息的Tag进行消息过滤。如:Consumer.subscribe (”TopicTest”,tag1 || tag2 || tag3”)。

DefaultMQPushConsumer 通过“长轮询”方式达到push效果,长轮询方式既有pull的优点,又兼具push方式的实时性。

push方式是server端接收到消息后,主动把消息推送给Client端,实时性高。 push方式的弊端:

  • 加大Server端的工作量,进而影响Server的性能
  • Client的处理能力各不相同,Client的状态不受Server控制,如果Client不能及时处理server推送过来的消息,会造成各种潜在问题。

pull方式是client端循环地从server端拉取消息,主动权在client手里,自己拉取到一定量的消息后,处理妥当了再接着取。 pull方式的问题主要是循环拉取的间隔不好确定,间隔太短就处在一个“忙等”的状态,浪费资源;
每个pull的时间间隔太长,Server端有消息到来时,有可能没有被及时处理。

“长轮询”的核心是, Broker端HOLD 住客户端过来的请求一小段时间 requestHeader.setSuspendTimeoutMillis (brokerSus- pendMaxTimeMillis),在这个时间内有新消息到达,就利用现有的连接立刻返回消息给 Consumer。
“长轮询”的 主动权还是掌握在 Consumer 手中, Broker 即使有大量消息积压 ,也不会主动推送给 Consumer 。
长轮询方式的局限性,是在 HOLD 住 Consumer 请求的时候需要占用资源,它适合用在消息队列这种客户端连接数可控的场景中。

PushConsumer的核心还是Pull方式。

DefaultMQPullConsumer

因为PullConsumer需要用户自己处理遍历Message Queue、保持Offset,所以有更多的自主性和灵活性。
主要处理额外三件事:

  1. 获取Message Queue并遍历
    一个Topic包括多个Message Queue,如果这个Consumer需要获取Topic下所有的消息,就要遍历所有的Message Queue。特殊情况也可以选择某些特定的Message Queue来获取消息。

  2. 维护Offset store
    从一个Message Queue里拉取消息的时候,要传人Offset参数( long类型 的值),随着不断读取消息 ,Offset会不断增长。这个时候由用户负责把Offset存储下来,根据具体情况可以存到内存里、写到磁盘或者数据库里等。

  3. 根据不同的消息状态做不同的处理
    拉取消息的请求发出后,会返回: FOUNDNO MATCHED MSGNO NEW MSGOFFSET ILLEGAL 四种状态,需要根据每个状态做不同的处理 。
    比较重要的两个状态是 FOUNTNO NEW MSG,分别表示获取到消息和没有新的消息 。

生产者向消息队列写入消息,不同的业务场景需要生产者采用不同的写入策略,比如同步发送、异步发送、延迟发送、发送事务性消息等。

DefaultMQProducer

生产者发送消息默认使用DefaultMQProducer,发送消息主要经过5个步骤:

  1. 设置Producer的GroupName
  2. 设置InstanceName
  3. 设置发送失败重试次数
  4. 设置NameServer地址
  5. 组装消息并发送

消息发送的返回状态有四种:

public enum SendStatus {
    SEND_OK,
    FLUSH_DISK_TIMEOUT,
    FLUSH_SLAVE_TIMEOUT,
    SLAVE_NOT_AVAILABLE;
    private SendStatus() {
    }
}
发送延迟消息

RockerMQ支持发送延迟消息,Broker收到这类消息后,延迟一段时间再处理,使消息在规定的一段时间后生效。

延迟消息的使用方法是在创建 Message对象时调用 setDelayTimeLevel ( int level) 方法设置延迟时间, 然后再把这个消息发送 出去。 目前延迟的时间不支持任意设置,仅支持预设值的时间长度 ( 1s/5s/1Os/30s/Im/2m/3m/4m/5m/6m/ 7m/8m/9m/1Om/20m/30m/1h/2h)。比如 setDelayTimeLevel(3)表示延迟10s。

事务消息

RocketMQ的事务消息,是指发送消息事件和其他事件需要同时成功或同时失败 。
RocketMQ事务性消息

Offset

RocketMQ 中, 一种类型的消息会放到一 个Topic 里,为了能够并行,一般一个Topic会有多个Message Queue (也可以设置成一个), Offset是指某个Topic下的一条消息在某个Message Queue里的位置,通过Offset的值可以定位到这条消息,或者指示 Consumer从这条消息 开始向后继续处理 。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值