RocketMQ消息队列

文章目录

  • 一、RocketMQ
    • 1. 什么是RocketMQ?
    • 2. RocketMQ的使用场景
    • 3. RocketMQ的原理
  • 二、RocketMQ的使用
    • 1. 导入依赖
    • 2. 启动类
    • 3. 配置文件
    • 4. 发送消息
    • 5. 接收消息
    • 6. 延迟消息


一、RocketMQ

1. 什么是RocketMQ?

RocketMQ是由阿里巴巴集团开发的一款分布式消息中间件。它是基于主题(Topic)的发布/订阅模式构建的,支持高并发、高可靠性的消息传递。它还提供了丰富的特性,如消息的事务性处理、消息的定时发送、消息的过滤和重试机制等。
RocketMQ还提供了可视化的管理控制台,方便管理和监控消息的发送和消费情况。

2. RocketMQ的使用场景

  • 限流消峰:
    MQ可以将系统的超量请求暂存其中,以便系统后期可以慢慢进行处理,防止系统在高峰期被过多的消息压力所冲垮。限流消峰可以有效地避免系统资源被耗尽,保证系统的稳定性和可靠性。
  • 异步消息处理:
    RocketMQ可用于解耦和异步处理系统之间的通信。通过将消息发送到RocketMQ中心,发送方可以立即返回而无需等待消息被消费。这种异步消息处理方式对于提高系统吞吐量和响应速度非常有益。
  • 日志收集和数据采集:
    RocketMQ提供了高吞吐量和低延迟的特性,使其非常适合作为日志收集和数据采集的中间件。各种系统和应用可以将生成的日志和数据发送到RocketMQ,并由专门的消费者进行处理和存储。
  • 分布式事务消息:
    RocketMQ支持分布式事务消息,可以在分布式环境下保证消息的原子性。这在需要跨多个系统进行数据一致性操作时非常有用,如订单支付过程中的库存扣减和账户余额变动等。
  • 消息广播:
    RocketMQ支持消息的广播模式,可以将消息发送到所有的消费者,适用于需要将消息广播给多个消费者的场景,如广告推送、实时通知等。

3. RocketMQ的原理

生产者会从NameService拉取Broker的路由信息,进行消息投递,通过指定的主题(Topic),以及标签,发送到特定的消息队列。然后消费者可以通过订阅特定的主题和标签,直接跟Broker建立连接通道,开始消费消息。

二、RocketMQ的使用

1. 导入依赖

<parent>
    <groupId> org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.2.5.RELEASEversion>
parent>
<dependencies>
    <dependency>
        <groupId>org.apache.rocketmqgroupId>
        <artifactId>rocketmq-spring-boot-starterartifactId>
       
         <version>2.2.1version>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
    dependency>
dependencies>

2. 启动类

@SpringBootApplication
public class ApplicationStart {
    public static void main(String[] args) {
        SpringApplication.run(ApplicationStart.class);
    }
}

3. 配置文件

rocketmq:
  name-server: 127.0.0.1:9876
  #生产者配置
  producer:
    #生产者组名字
    group: "service-producer"
    # 消息最大长度 默认 1024 * 1024 * 4 (4M)
    max-message-size: 4194304
    # 发送消息超时时间,默认 3000
    send-message-timeout: 3000
    # 发送消息失败重试次数,默认2
    retry-times-when-send-failed: 2
    # 异步消息发送失败重试次数
    retry-times-when-send-async-failed: 2
    #达到 4096 ,进行消息压缩
    compress-message-body-threshold: 4096
  consumer:
    #消费者名字
    group: "service-consumer"
    #批量拉取消息数量
    pull-batch-size: 10
    message-model: CLUSTERING
    selector-expression: "*"

4. 发送消息

  • 第一种:同步消息
    MQ提供了RocketMQTemplate来发送消息;
    同步消息是发送者发送消息,需要等待结果的返回,才能继续发送第二条消息。
package top.itimmortal.controller;

@RestController
@RequestMapping("/send")
public class RocketMQController {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @GetMapping("/order/{name}")
    public String sendMsg(@PathVariable("name") String name){
    	//需要发送的消息
        Message<String> message = MessageBuilder.withPayload(name).build();
        //"topic-order:tags-order-pay":指定主题和标签
        rocketMQTemplate.send("topic-order:tags-order-pay",message);
        return "发送完成";
    }
}

除了使用send发送同步消息,还可以使用synSend,该方法更加灵活:

package top.itimmortal.controller

@RestController
@RequestMapping("/sync")
public class SyncSenController {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @RequestMapping("order/{name}")
    public String sync(@PathVariable("name") String name){
        Message<String> message = MessageBuilder.withPayload(name).build();
        //发送同步消息,1s发送不成功就超时
        SendResult syncSend = rocketMQTemplate.syncSend("topic-order:tags-order-pay", message, 1000);
        //判断是否超时
        if (syncSend.getSendStatus() == SendStatus.SEND_OK) {
            return "发送成功";
        }
        return "发送失败";
    }
}
  • 第二种:异步发送
    异步消息是发送者发送消息,无需等待发送结果就可以再发送第二条消息,它是通过回调的方式来获取到消息的发送结果,消息可靠性高,性能也高。
package top.itimmortal.controller;

@RestController
@RequestMapping("/async")
public class AsyncSendController {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @RequestMapping("order/{name}")
    public String sync(@PathVariable("name") String name){
    	//需要发送的消息
        Message<String> message = MessageBuilder.withPayload(name).build();
        //"topic-order:tags-order-pay":主题和标签
        rocketMQTemplate.asyncSend("topic-order:tags-order-pay", message, new SendCallback() {//消息发送结果回调
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("成功");
            }
            @Override
            public void onException(Throwable throwable) {
                System.out.println("失败");
            }
        });
        return "发送";
    }
}
  • 第三种:单向发送
    这种方式指的是发送者发送消息后无需等待Broker的结果返回,Broker也不会返回结果,该方式性能最高,但是消息可靠性低。
package top.itimmortal.controller;

@RestController
@RequestMapping("/sendOneWay")
public class SendOneWayController {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @RequestMapping("order/{name}")
    public String sync(@PathVariable("name") String name){
        Message<String> message = MessageBuilder.withPayload(name).build();
        //直接发送,不会返回任何信息
        rocketMQTemplate.sendOneWay("topic-order:tags-order-pay",message);
        return "发送成功";
    }
}

5. 接收消息

MQ提供消息监听器:RocketMQListener,他会负责监听MQ中的消息从而进行消费。

package top.itimmortal.controller;

import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

@Component
@RocketMQMessageListener(
        //消费者的名字
        consumerGroup = "consumer-ordet",
        //主题
        topic = "topic-order",
        //tags
        selectorExpression = "tags-order-pay",
        //消息消费模式:默认是CLUSTERING集群,还支持BROADCASTING广播
        messageModel = MessageModel.CLUSTERING)
//消费者监听器    MessageExt:Message对象的子类
public class ConsumerController implements RocketMQListener<MessageExt> {
    @Override
    public void onMessage(MessageExt message) {
        //这里拿到的消息 message.getBody 是byte[]格式。
        if(message.getBody() == null ||message.getBody().length == 0)return;
        //拿到消息:如果发送的消息是字符串,那么需要把byte[]转为字符串
        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
        System.out.println(msg);
    }
}

6. 延迟消息

把消息写到Broker后需要延迟一定时间才能被消费 , 在RocketMQ中消息的延迟时间不能任意指定,而是由特定的等级(1 到 18)来指定,分别有:

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

这里还是使用同步消息做测试:

package top.itimmortal.controller;

@RestController
@RequestMapping("/sync")
public class SyncSenController {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @RequestMapping("order/{name}")
    public String sync(@PathVariable("name") String name){
        Message<String> message = MessageBuilder.withPayload(name).build();
        SendResult syncSend = rocketMQTemplate.syncSend("topic-order:tags-order-pay", message, 1000,3);//等级是 3,对应的是 10S
        //判断
        if (syncSend.getSendStatus() == SendStatus.SEND_OK) {
            return "发送成功";
        }
        return "发送失败";
    }
}

你可能感兴趣的:(rocketmq,rocketmq)