1 单生产者单消费者消息发送

1.1 新建maven项目

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.9.0</version>
</dependency>

1.2 生产者

public class Producer {
    public static void main(String[] args) throws Exception {
        // 谁来发
        DefaultMQProducer producer = new DefaultMQProducer("group1");
        // 发给谁
        producer.setNamesrvAddr("localhost:9876");
        producer.start();
        // 消息主体
        Message msg = new Message("topic1", "hello rocketmq".getBytes("UTF-8"));
        // 获取结果
        SendResult result = producer.send(msg);
        System.out.println("返回结果:" + result);
        // 关闭连接
        producer.shutdown();
    }
}

springboot rocketmq发消息指定队列_rcketmq

1.3 消费者

public class Consumer {
    public static void main(String[] args) throws Exception {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
        consumer.setNamesrvAddr("localhost:9876");
        //3.设置接收消息对应的topic,对应的sub标签为任意
        consumer.subscribe("topic1","*");
        //3.开启监听,用于接收消息
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                //遍历消息
                for (MessageExt msg : list) {
                    System.out.println("收到消息:"+msg);
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
        System.out.println("接受消息服务已经开启!");
    }
}

springboot rocketmq发消息指定队列_User_02

2 单生产者多消费者消息发送

单生产者产生的消息可以被同一个消费者消费,也可以被多个消费者消费

生产者发送十条消息

for (int i = 0; i < 10; i++) {
     String message = "hello rocketmq" + i;
     Message msg = new Message("topic2", message.getBytes("UTF-8"));
     // 获取结果
     SendResult result = producer.send(msg);
     System.out.println("返回结果:" + result);
 }

消费者消费消息

允许多次启动

springboot rocketmq发消息指定队列_rcketmq_03

启动两个消费者,这个时候会出现每个消费者收到五个消息。(负载均衡模式:默认模式)

要想让生产者生产的消息每个消费者都全部获取,可以将负载均衡模式改为广播模式或
通过修改组名,每个消费者组名不同就可以全部获取

DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");

即集群模式下,同个主题对于不同组是“广播模式”,每个组都会消费同个消息;会重复消费;对于同个组是“集群模式”,每个消费者平坦消息,不会重复消费;

springboot rocketmq发消息指定队列_User_04

思考: Consumerl、2同组就要都收到全部10条消息?

消费模式默认是MessageModel.CLUSTERING

springboot rocketmq发消息指定队列_消息发送_05

现在我把它设置为 BROADCASTING模式

consumer.setMessageModel(MessageModel.BROADCASTING);

3 消息类别

3.1 同步消息

一条消息发送并且接收到返回消息后才发送下一条消息,常用于类似于邮件发送、短信发送的场景

特征:即时性较强,重要的消息,且必须有回执的消息,例如短信,通知(转账成功)

3.2 异步消息

特征:即时性较弱,但需要有回执的消息,例如订单中的某些信息

下面是生产者异步发送的代码,producer.send(msg, sendCallback()) 是异步的,下面代码会先打印异步发送完成,再打印消息结果。因此之前写的producer.shutdown();要删掉,不然会先执行producer.shutdown();再执行异步方法,导致没有producer。

for (int i = 0; i < 10; i++) {
    String message = "hello rocketmq + 异步" + i;
    Message msg = new Message("topic3", message.getBytes("UTF-8"));
    producer.send(msg, new SendCallback() {
        @Override
        public void onSuccess(SendResult sendResult) {
            System.out.println(sendResult);
        }

        @Override
        public void onException(Throwable throwable) {
            // 业务逻辑
            System.out.println(throwable);
        }
    });
    System.out.println("异步发送完成");
}

springboot rocketmq发消息指定队列_消息发送_06

3.3 单向消息

特征:不需要有回执的消息,例如日志类消息

producer.sendOneway(message);

3.3 延时消息

特征:消息发送时并不直接发送到消息服务器,而是根据设定的等待时间到达,起到延时到达的缓冲作用

可以给每个消息设置延时

// 设置延迟时间为等级3
msg.setDelayTimeLevel(3);
SendResult sendResult = producer.send(msg);

目前支持的延时类型有:

springboot rocketmq发消息指定队列_List_07

3.4 批量消息

特征:一次发送多条消息,节约网络开销

生产者发送一次消息就要和nameServer建立连接,和broker建立连接,在真实环境中每秒可以发几万甚至几十万的消息,会造成连接过多系统性能下降。而批量发送就可以集中一次发送。

String msg = "hello rocketmq producer batch";
List<Message> messageList = new ArrayList<>();
for (int i = 0; i < 4; i++) {
    Message message = new Message("topic4", msg.getBytes(StandardCharsets.UTF_8));
    messageList.add(message);
}
producer.send(messageList);

springboot rocketmq发消息指定队列_rcketmq_08

4 消息过滤

4.1 tag 过滤

springboot rocketmq发消息指定队列_消息发送_09

4.2 sql过滤

使用 SQL 过滤, 需要在broker.conf文件中添加配置enablePropertyFilter=true

springboot rocketmq发消息指定队列_消息发送_10

在生产者中追加属性

Message msg = new Message("topic6", "tag3","hello rocketmq".getBytes("UTF-8"));
 // 给消息追加属性
 msg.putUserProperty("name", "zhangsan");
 msg.putUserProperty("age", "12");

在消费者过滤

consumer.subscribe("topic6", MessageSelector.bySql("age > 16"));

springboot rocketmq发消息指定队列_List_11

5 SpringBoot整合RocketMQ

5.1 项目搭建

5.1.1 依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.rocketmq</groupId>
        <artifactId>rocketmq-spring-boot-starter</artifactId>
        <version>2.2.1</version>
    </dependency>
</dependencies>
5.1.3 producer 服务搭建

yml文件

rocketmq:
  name-server: localhost:9876
  producer:
    group: group1
server:
  port: 8088

实现

@Autowired
private RocketMQTemplate rocketMQTemplate;

@GetMapping("send")
public String send() {
    User user = new User("cc", 19);
    rocketMQTemplate.convertAndSend("topic10", user);
    return "success";
}
5.1.3 consumer 服务搭建

yml文件

server:
  port: 8089
rocketmq:
  name-server: localhost:9876
  producer:
    group: group1

servie监听

@Service
@RocketMQMessageListener(topic = "topic10", consumerGroup = "group1")
public class ConsumerService implements RocketMQListener<User> {
    @Override
    public void onMessage(User user) {
        System.out.println(user);
    }
}

5.2 其他功能

5.2.1 消息类别
@GetMapping("send")
public String send() {
    User user = new User("cc", 19);
    rocketMQTemplate.convertAndSend("topic10", user);
    return "success";
}

@GetMapping("syncSend")
public String syncSend() {
    User user = new User("cc", 19);
    SendResult result = rocketMQTemplate.syncSend("topic10", user);
    return "同步发送成功";
}

@GetMapping("asyncSend")
public String asyncSend() {
    User user = new User("cc", 19);
    rocketMQTemplate.asyncSend("topic10", user, new SendCallback() {
        @Override
        public void onSuccess(SendResult sendResult) {
            System.out.println(sendResult);
        }

        @Override
        public void onException(Throwable throwable) {
            System.out.println(throwable);
        }
    }, 1000);
    return "异步发送成功";
}

@GetMapping("sendOneWay")
public String sendOneWay() {
    User user = new User("cc", 19);
    rocketMQTemplate.sendOneWay("topic10", user);
    return "单向消息发送成功";
}

@GetMapping("sendDelayLevel")
public String sendDelayLevel() {
    User user = new User("cc", 19);
    rocketMQTemplate.syncSend("topic10", MessageBuilder.withPayload(user).build(), 2000, 3);
    return "延时消息发送成功";
}

@GetMapping("sendMatch")
public String sendMatch() {
    List<User> users= new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        User user = new User("小" + i, i);
        users.add(user);
    }
    rocketMQTemplate.syncSend("topic10", users, 1000);
    return "批量发送成功";
}
5.2.2 消息过滤
5.2.2.1 tag过滤
@RocketMQMessageListener(topic = "topic10", consumerGroup = "group1", selectorExpression = "tag1 || tag2")
5.2.2.2 sql过滤
@RocketMQMessageListener(topic = "topic10", consumerGroup = "group1", selectorType = SelectorType.SQL92,
        selectorExpression = "age >= 18", messageModel = MessageModel.BROADCASTING)