RocketMQ 5.x版本 Spring Boot Starter脚手架

4,963 阅读3分钟

背景

RocketMQ client有两个版本,4.x及以下版本是基于remoting协议,连接端点为'name server';当前的5.x版本是基于新的gRpc/protobuf协议, 连接端点为'proxy server',适合于新的存储和计算分离架构。

RocketMQ官方已有一个spring boot starter脚手架,是基于remoting协议版本的client, 由于5.x版本与4.x及以下版本API不同,故不适用5.x版本。 在开发此项目时官方没有维护5.x系列的spring boot starter脚手架,因工作需要开发了此rocketmq-java-spring-boot-starter脚手架。只适用于5.x版本 RocketMQ,若在用老版本的服务,请仍使用老版本的脚手架。

功能

  • 同步方式发送消息
  • 异步方式发送消息
  • 支持发送普通/顺序/定时延迟消息
  • 暂不支持事务消息
  • PushConsumer方式消费消息
  • SimpleConsumer方式消费消息(开发中)
  • 支持用tag或SQL92表达式过滤消息
  • 支持鉴权和认证

前提要求

  • JDK 1.8及以上
  • Maven 3.0及以上
  • Spring 2.x 系列版本

使用方法

此脚手架版本跟随官方rocketmq-client-java版本进行迭代。

源码地址: rocketmq-java-spring-boot-starter

git clone下载源码,构建打包, mvn -Dmaven.test.skip=true -Dgpg.skip clean install

然后添加Maven依赖,

<dependency>
    <groupId>cn.baiyang.rocketmq</groupId>
    <artifactId>rocketmq-java-spring-boot-starter</artifactId>
    <version>5.0.5</version>
</dependency>

主要RocketMQ使用配置(完整见API),

rocketmq-java:
  endpoints: {abcd.rmq.aliyuncs.com:8080}
  accesskey: {accesskey}
  secretkey: {secretkey}
  enable-ssl: true
  producer:
    topics: {topics seperated with comma}

Producer

脚手架根据配置会默认提供一个defaultProducer,在代码中直接使用即可;defaultProducer支持发送普通消息、顺序消息、延迟消息,不支持事务消息。 也可以定义自己的Producer,或定义多个。

Spring框架通常会遵循Spring Messaging风格,提供一个template来封装支持常见消息发送操作;这里没有遵循此风格,主要是为了简化明了,符合实际 需要最简单;且template里面封装了太多一般不需要的API,看起来费事费力。此脚手架提供了一个类似的AbstractRocketMQSender封装类,目的是为了 保证发送方一定要提供topic,tag或messageGroup参数;同时参数最好以应用配置的形式存在。写一个继承该封装类的对象,再通过setProducer方法注入 spring初始化好的Producer实例即可。可以是defaultProducer也可以是其他自定义的。

样例配置,

rocketmq-java:
  endpoints: {abcd.rmq.aliyuncs.com:8080}
  accesskey: {accesskey}
  secretkey: {secretkey}
  enable-ssl: true
  producer:
    topics: {biz_ecom-example}

yourbusiness:
  topic: {biz_ecom-example}
  tag: {create-example}

样例代码,

import cn.baiyang.rocketmq.spring.core.AbstractRocketMQSender;

import javax.annotation.Resource;

import org.apache.rocketmq.client.apis.producer.Producer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ProducerExample extends AbstractRocketMQSender {

    protected ProducerExample(@Value("${yourbusiness.topic}") String topic, @Value("${yourbusiness.tag}") String tag) {
        super(topic, tag);
    }

    @Resource
    @Qualifier("defaultProducer")
    @Override
    protected void setProducer(Producer producer) {
        this.producer = producer;
    }
}

Consumer

脚手架提供完全以annotation的方式来完成一个Consumer,支持所有的配置。实现一个Consumer只需要实现RocketMQListener接口, 并配置RocketMQMessageListener标注即可。 具体的配置信息见RocketMQMessageListener对象。

样例配置(这些配置也都支持在Consumer对象标注上来设置),

rocketmq-java:
  endpoints: {abcd.rmq.aliyuncs.com:8080}
  accesskey: {accesskey}
  secretkey: {secretkey}
  enable-ssl: true

yourbusiness:
  topic: {biz_ecom-example}
  tag: {create-example}
  consumer-group: {creating-group-example}

样例代码,

import cn.baiyang.rocketmq.spring.annotation.RocketMQMessageListener;
import cn.baiyang.rocketmq.spring.annotation.SelectorType;
import cn.baiyang.rocketmq.spring.core.RocketMQListener;
import cn.baiyang.rocketmq.spring.core.RocketMQListenerHelper;

import org.apache.rocketmq.client.apis.consumer.ConsumeResult;
import org.apache.rocketmq.client.apis.message.MessageView;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RocketMQMessageListener(
    topic = "${yourbusiness.topic}",
    consumerGroup = "${yourbusiness.consumer-group}",
    selectorType = SelectorType.TAG,
    selectorExpression = "${yourbusiness.tag}"
)
public class ListenerExample extends RocketMQListenerHelper implements RocketMQListener {

    @Override
    public ConsumeResult consume(MessageView messageView) {
        log.info("message: {}; --> body: {}", messageView, getBodyAsString(messageView));
        //TODO Business Logic Here
        return ConsumeResult.SUCCESS;
    }

}

: RocketMQListenerHelper是一个工具类,提供了从MessageView获取消息体的方法byte[] getBody(MessageView messageView)String getBodyAsString(MessageView messageView),增加代码复用能力。你也可以不继承这个工具类,完全自己来写。

脚手架目前没有提供MessageConverter的自动封装能力,因为这不是核心流程。 大家拿到消息体byte[]数组或String字符串对象后,自己可以根据业务上下游定义的数据格式,来对数据做处理,比如json反序列化等。 另一方面,如果完全封装后,一则可能仍然需要自己在代码中定义MessageConverter对象;二则如果想要拿到原始的MessageView对象, 比如看消息的properties等,就不用再做额外配置。 后续再提供MessageConverter的封装。

样例代码

rocketmq-java-spring-boot-example