RocketMQ4.9.4在SpringBoot项目中使用

一、介绍

发布-订阅(Pub/Sub)是一种消息范式,消息的发送者(称为发布者、生产者、Producer)会将消息直接发送给特定的接收者(称为订阅者、消费者、Comsumer)。而RocketMQ的基础消息模型就是一个简单的Pub/Sub模型。

1)生产者

负责生产消息,一般由业务系统负责生产消息。一个消息生产者会把业务应用系统里产生的消息发送到broker服务器。RocketMQ提供多种发送方式,同步发送、异步发送、顺序发送、单向发送。

消息

RocketMQ支持的发送消息类别包括:普通消息、顺序消息、延迟消息、批量消息、事务消息

Message 可以设置的属性值包括:

字段名 默认值 必要性 说明
Topic null 必填 消息所属 topic 的名称
Body null 必填 消息体
Tags null 选填 消息标签,方便服务器过滤使用。目前只支持每个消息设置一个
Keys null 选填 代表这条消息的业务关键词
Flag 0 选填 完全由应用来设置,RocketMQ 不做干预
DelayTimeLevel 0 选填 消息延时级别,0 表示不延时,大于 0 会延时特定的时间才会被消费
WaitStoreMsgOK true 选填 表示消息是否在服务器落盘后才返回应答。

2)消费者

负责消费消息,一般是后台系统负责异步消费。一个消息消费者会从Broker服务器拉取消息、并将其提供给应用程序。从用户应用的角度而言提供了两种消费形式:拉取式消费、推动式消费。

在 Apache RocketMQ 有两种消费模式,分别是:

  • 集群消费模式:当使用集群消费模式时,RocketMQ 认为任意一条消息只需要被消费组内的任意一个消费者处理即可。
  • 广播消费模式:当使用广播消费模式时,RocketMQ 会将每条消息推送给消费组所有的消费者,保证消息至少被每个消费者消费一次。

集群模式下,同一个消费组内的消费者会分担收到的全量消息。
Apache RocketMQ 提供了多种集群模式下的分配策略,包括平均分配策略、机房优先分配策略、一致性hash分配策略等,可以通过如下代码进行设置相应负载均衡策略

consumer.setAllocateMessageQueueStrategy(new AllocateMessageQueueAveragely());

默认的分配策略是平均分配,这也是最常见的策略。平均分配策略下消费组内的消费者会按照类似分页的策略均摊消费。

在平均分配的算法下,可以通过增加消费者的数量来提高消费的并行度。

3)主题

表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。

二、工程配置

1)引入依赖jar包

扫描二维码关注公众号,回复: 15061129 查看本文章
<!-- rocketmq-spring-boot-starter -->
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

2)在application.yml中增加链接配置

## 服务链接配置
rocketmq:
  name-server: 192.168.56.110:9876
  producer:
    group: demo_group
    send-message-timeout: 30000
## 示例topic配置
app:
  rocketmq:
    demo-string-topic: demo_string_topic
    demo-string-group: demo_string_group
    demo-order-topic: demo_order_topic
    demo-order-group: demo_order_group

属性配置类

@Component
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ConfigurationProperties(prefix = "app.rocketmq")
public class RocketmqCustomProperties {
    
    

    private String demoStringTopic;
    private String demoStringGroup;
    private String demoOrderTopic;
    private String demoOrderGroup;
}

三、示例java代码

1)传输的Dto,OrderMessage.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderMessage {
    
    

    private String orderSn;

    private String newStatus;

    private String paymentMethod;
}

2)信息标签枚举类,OrderTagsEnum.java

public enum OrderTagsEnum {
    
    

    ORDER_CREATE("订单创建"),
    STATUS_CHANGE("订单状态改变");

    private final String description;

    OrderTagsEnum(String description) {
    
    
        this.description = description;
    }

    public String description() {
    
    
        return description;
    }
}

3)信息监听器,OrderMessageListener.java

@Component
@Slf4j
@RocketMQMessageListener(topic = "${app.rocketmq.demo-order-topic}", consumerGroup = "${app.rocketmq.demo-order-group}")
public class OrderMessageListener implements RocketMQListener<MessageExt> {
    
    

    @Override
    public void onMessage(MessageExt messageExt) {
    
    
        try {
    
    
            OrderMessage data = JSONUtil.toBean(new String(messageExt.getBody()),OrderMessage.class);
            log.info("onMessage:{}", JSONUtil.toJsonStr(messageExt));
            log.info("tags:{}", messageExt.getTags());
            log.info("data:{}", JSONUtil.toJsonStr(data));
        } catch (Exception e) {
    
    
            log.error("事件调用异常", e);
        }
    }

}

4)信息发送回调工具类

@Slf4j
public class RocketmqSendCallback implements SendCallback {
    
    
    @Override
    public void onSuccess(SendResult sendResult) {
    
    
        log.info("async onSuccess SendResult={}", sendResult);
    }

    @Override
    public void onException(Throwable throwable) {
    
    
        log.error("async onException Throwable", throwable);
    }
}
public class RocketmqSendCallbackBuilder {
    
    
    public static RocketmqSendCallback commonCallback() {
    
    
        return new RocketmqSendCallback();
    }
}

5)信息发送测试类,TestRocketmqProducer.java

@Slf4j
@Component
public class TestRocketmqProducer {
    
    
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private RocketmqCustomProperties rocketmqCustomProperties;

    public void send() {
    
    

        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setOrderSn("001");
        orderMessage.setPaymentMethod("test");
        orderMessage.setNewStatus("PAID");

        String destination = rocketmqCustomProperties.getDemoOrderTopic() + ":"+ OrderTagsEnum.STATUS_CHANGE.name();
        //发送订单变更mq消息
        rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(orderMessage), RocketmqSendCallbackBuilder.commonCallback());

    }
}

6)测试数据输出

发送

async onSuccess SendResult=SendResult [sendStatus=SEND_OK, msgId=7F0000018FA018B4AAC273EDD72D0003, offsetMsgId=2F6842B200002A9F000000000000195F, messageQueue=MessageQueue [topic=demo_order_topic, brokerName=broker-a, queueId=0], queueOffset=7]

接收

c.s.f.r.l.OrderMessageListener - [onMessage,20] - onMessage:{"brokerName":"broker-a","queueId":0,"storeSize":350,"queueOffset":7,"sysFlag":0,"bornTimestamp":1677125766957,"bornHost":"/61.173.76.130:48861","storeTimestamp":1677125766990,"storeHost":"/47.104.66.178:10911","msgId":"7F0000018FA018B4AAC273EDD72D0003","commitLogOffset":6495,"bodyCRC":1890944630,"reconsumeTimes":0,"preparedTransactionOffset":0,"topic":"demo_order_topic","flag":0,"properties":{"MIN_OFFSET":"0","MAX_OFFSET":"8","CONSUME_START_TIME":"1677125766993","id":"b8746c23-91ec-6b10-714e-48ddde3a1738","UNIQ_KEY":"7F0000018FA018B4AAC273EDD72D0003","CLUSTER":"DefaultCluster","contentType":"text/plain;charset=UTF-8","TAGS":"STATUS_CHANGE","timestamp":"1677125766930"}}
c.s.f.r.l.OrderMessageListener - [onMessage,21] - tags:STATUS_CHANGE
c.s.f.r.l.OrderMessageListener - [onMessage,22] - data:{"orderSn":"001","newStatus":"PAID","paymentMethod":"test"}

参考

  • https://rocketmq.apache.org/zh/docs/4.x/

猜你喜欢

转载自blog.csdn.net/wlddhj/article/details/129186055