ROCKETMQ学习总结1入门

MQ 作用:应用解耦 、流量削峰 、数据分发

常见的MQ产品包括Kafka、ActiveMQ、RabbitMQ、RocketMQ。

RocketMQ组成角色:

ROCKETMQ学习总结1入门

Producer:消息的发送者; Consumer:消息接收者; Broker:暂存和传输消息; NameServer:管理Broker; Topic:区分消息的种类; Message Queue:相当于是Topic的分区;用于并行发送和接收消息 。

高可用的保障:集群搭建:单Master模式、多Master模式、多Master多Slave模式(异步:主备有短暂消息延迟 )、多Master多Slave模式(同步:只有主备都写成功,才向应用返回成功,可用性高但性能比异步低10%左右 )

集群工作流程:

  1. 启动NameServer,NameServer起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。

  2. Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。

  3. 收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。

  4. Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。

  5. Consumer跟Producer类似,跟其中一台NameServer建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,开始消费消息。

集群控制台:rocketmq-console

消息发送基本步骤:

1.创建消息生产者producer,并制定生产者组名
2.指定Nameserver地址
3.启动producer
4.创建消息对象,指定主题Topic、Tag和消息体
5.发送消息
6.关闭生产者producer

1.创建消费者Consumer,制定消费者组名
2.指定Nameserver地址
3.订阅主题Topic和Tag
4.设置回调函数,处理消息
5.启动消费者consumer

发送消息:

1、同步方式发送消息:producer.send(msg);

2、异步方式发送消息:producer.send(msg, new SendCallback() {处理异步返回} )

3、发送单向消息:producer.sendOneway(msg);

消息消费:

1)负载均衡模式:每个消费者处理的消息不同:consumer.setMessageModel(MessageModel.CLUSTERING);

2)广播模式:每个消费者消费的消息都是相同的 consumer.setMessageModel(MessageModel.BROADCASTING);

// 注册回调函数,处理消息
consumer.registerMessageListener(new MessageListenerConcurrently() {}

 

增强的消息发送消费模式:顺序消息、延时消息、批量消息、过滤消息、事务消息

1、顺序消息:RocketMQ可以严格的保证消息有序,可以分为分区有序或者全局有序。 默认的情况下消息发送会采取Round Robin轮询方式把消息发送到不同的queue(分区队列), 消费消息的时候从多个queue上拉取消息无法保证有序所以要控制发送的顺序消息只依次发送到同一个queue中,消费的时候只从这个queue上依次拉取,则就保证了顺序。全局有序:发送和消费参与的queue只有一个;分区有序:多个queue参与。

方式:producer.send(msg, new MessageQueueSelector(List<MessageQueue> mqs, Message msg, Object arg) {实现MessageQueueSelector中的select方法返回需要进入的MessageQueue},Object arg) {};订单号相同的消息会被先后发送到同一个队列 select方法内对订单号取模计算queue;

设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费, 如果非第一次启动,那么按照上次消费的位置继续消费
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

consumer.subscribe("TopicTest", "TagA || TagC || TagD");// 订阅Topics

consumer.registerMessageListener(new MessageListenerOrderly() {// 每个queue有唯一的consume线程来消费, 订单对每个queue(分区)有序}

延时消费:

message.setDelayTimeLevel(3);// 设置延时等级3,这个消息将在10s之后发送(现在只支持固定的几个时间,详看delayTimeLevel)
producer.send(message); // 发送消息

 // 消费者注册消息监听者
  consumer.registerMessageListener(new MessageListenerConcurrently() {XXX}

注意:现在RocketMq并不支持任意时间的延时,需要设置几个固定的延时等级,从1s到2h分别对应着等级1到18 :

private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";

批量消息:

批量消息应该有相同的topic ,一批消息的总大小不应超过4MB。

List<Message> messages = new ArrayList<>();

messages .add(msg).add(msg).....

producer.send(messages);

过滤消息:

TAG 过滤、SQL过滤。只有使用push模式的消费者才能用使用SQL92标准的sql语句

// 设置一些属性
msg.putUserProperty("a", String.valueOf(i));
SendResult sendResult = producer.send(msg);

// 只有订阅的消息有这个属性a, a >=0 and a <= 3
consumer.subscribe("TopicTest", MessageSelector.bySql("a between 0 and 3");
consumer.registerMessageListener(new MessageListenerConcurrently() {XXX};

事务消息:

实现机制:

1、事务消息发送及提交:(1) 发送消息(half消息)。(2) 服务端响应消息写入结果。(3) 根据发送结果执行本地事务(如果写入失败,此时half消息对业务不可见,本地逻辑不执行)。(4) 根据本地事务状态执行Commit或者Rollback(Commit操作生成消息索引,消息对消费者可见)

2、事务补偿(解决消息Commit或者Rollback发生超时或者失败的情况):(1) 对没有Commit/Rollback的事务消息(pending状态的消息),从服务端发起一次“回查”(2) Producer收到回查消息,检查回查消息对应的本地事务的状态(3) 根据本地事务状态,重新Commit或者Rollback。

事务消息共有三种状态,提交状态(允许消费 )、回滚状态(已删除消息)、中间状态 (需要检查消息队列来确定状态 )

/创建事务监听器
TransactionListener transactionListener = new TransactionListenerImpl();
//创建消息生产者
TransactionMQProducer producer = new TransactionMQProducer("group6");

producer.setTransactionListener(transactionListener);

//启动消息生产者
producer.start();

其中TransactionListenerImpl实现接口TransactionListener,它返回前一节中提到的三个事务状态之一,检查本地事务状态

限制:不支持延时消息和批量消息;默认单个消息的检查次数限制为 15 次,检查某条消息超过 N 次的话( N = transactionCheckMax ) 则 Broker 将丢弃此消息,并在默认情况下同时打印错误日志。用户可以通过重写 AbstractTransactionCheckListener 类来修改这个行为;事务消息的生产者 ID 不能与其他类型消息的生产者 ID 共享。与其他类型的消息不同,事务消息允许反向查询、MQ服务器能通过它们的生产者 ID 查询到消费者。

我们公司的推送流程:

ROCKETMQ学习总结1入门

ROCKETMQ学习总结1入门