Spring Boot和Spring Cloud整合Rocket

98 阅读2分钟

Spring Boot

发送普通消息

引入依赖

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.1.1</version>
</dependency>

编写配置文件

# 应⽤名称
spring.application.name=my-boot-rocketmq-demo
# 应⽤服务 WEB 访问端⼝
server.port=8080
# nameserver地址
rocketmq.name-server=192.168.150.102:9876
# 配置⽣产者组
rocketmq.producer.group=my-producer-boot-group1

⽣产者

@Component
public class MyProducer {
​
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
​
    /**
     * 发送消息
     * @param msg 消息内容
     * @param topic ⽬标主题
     */
    public void sendMessage(String msg,String topic){
        //将msg转换成Message对象并发送
        rocketMQTemplate.convertAndSend(msg);
    }
}

JUnit单元测试

@Test
void testSendMessage(){
    MyProducer producer = new MyProducer();
    String topic="MyBootTopic";
    String msg="hello spring boot rocketmq";
    producer.sendMessage(msg,topic);
}

消费者

@Component
@RocketMQMessageListener(consumerGroup = "my-boot-consumer-group",topic = "MyBootTopic")
public class MyConsumer implements RocketMQListener<String> {
​
    @Override
    public void onMessage(String msg) {
        System.out.println("收到的消息:" + msg);
    }
}

发送事务消息

⽣产者

public void sendMessageInTransaction(String msg, String topic) throws Exception {
    //创建不同的消息组
    String[] tags = new String[]{"TagA", "TagB", "TagC","TagD", "TagE"};
    for (int i = 0; i < 10; i++) {
        Message<String> message = MessageBuilder.withPayload(msg).build();
        //topic和tag整合在⼀起,以":"隔开
        String destination = topic+":"+tags[i % tags.length];
        //第⼀个destination为消息要发到的⽬的地,第⼆个destination为 消息携带的业务数据
        TransactionSendResult sendResult =
                rocketMQTemplate.sendMessageInTransaction(destination, message,destination);
        System.out.println(sendResult);
        Thread.sleep(10);
    }
}

事务监听器

@RocketMQTransactionListener(rocketMQTemplateBeanName = "rocketMQTemplate")
public class MyTransactionListenerImpl implements RocketMQLocalTransactionListener {
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        //获得业务参数中的数据
        String destination = (String) arg;
        //使⽤RocketMQUtil将spring的message转换成rocketmq的message
        org.apache.rocketmq.common.message.Message message =
                RocketMQUtil.convertToRocketMessage(new StringMessageConverter(),
                        "utf-8", destination, msg);
        //获得消息中的业务数据tags
        String tags = message.getTags();
        if (StringUtils.contains(tags,"TagA")){
            //提交本地事务
            return RocketMQLocalTransactionState.COMMIT;
        }else if (StringUtils.contains(tags,"TagB")){
            //回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        }else {
            //中间状态
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
​
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        return null;
    }
}

消费者同上

Spring Cloud

Spring Cloud Stream介绍

Spring Cloud Stream 是⼀个框架,⽤于构建与共享消息系统连接的⾼度可扩展的事 件驱动微服务。 该框架提供了⼀个灵活的编程模型,该模型基于已经建⽴和熟悉的 Spring 习惯⽤法 和最佳实践,包括对持久 pub/sub 语义、消费者组和有状态分区的⽀持。 Snipaste_2023-11-08_12-04-51.png Spring Cloud Stream 的核⼼构建块是:

  • Destination Binders:负责提供与外部消息传递系统集成的组件。

    • 各种消息队列对应蓝色部分
  • Destination Bindings:外部消息系统和最终⽤户提供的应⽤程序代码(⽣产者/ 消费者)之间的桥梁。

  • Message:⽣产者和消费者⽤来与⽬标绑定器(以及通过外部消息系统的其他 应⽤程序)进⾏通信的规范数据结构。

导入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-acl</artifactId>
        </exclusion>
    </exclusions>
</dependency><dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.7.1</version>
</dependency>
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-acl</artifactId>
    <version>4.7.1</version>
</dependency>

编写配置⽂件

# 应⽤名称
spring.application.name=my-s-rocketmq-demo
# 应⽤服务 WEB 访问端⼝
server.port=8080
# output ⽣产者
spring.cloud.stream.bindings.output.destination=TopicTest
# 配置rocketMQ
spring.cloud.stream.rocketmq.binder.name-server=192.168.150.102:9876

启动类上添加注解

@EnableBinding(Source.class)

@EnableBinding(Source.class) 指向的是配置⽂件的output参数。

⽣产者

@Component
public class MyProducer {
​
    @Resource
    private Source source;
​
    public void sendMessage(String msg){
        Map<String, Object> headers = new HashMap<>();
        //key:常量,它表示消息标签的属性键,value:属性标签
        headers.put(MessageConst.PROPERTY_TAGS,"TagA");
        MessageHeaders messageHeaders = new MessageHeaders(headers);
        Message<String> message = MessageBuilder.createMessage(msg, messageHeaders);
        source.output().send(message);
    }
}

单元测试

@SpringBootTest
public class api_test {
​
    @Autowired
    private MyProducer producer;
    @Test
    void testSendMessage(){
        producer.sendMessage("hello spring cloud stream");
    }
}

消费者

依赖同上

配置文件

# 应⽤名称
spring.application.name=my-s-rocketmq-demo
# 应⽤服务 WEB 访问端⼝
server.port=8081
# input 消费者
spring.cloud.stream.bindings.input.destination=TopicTest
spring.cloud.stream.bindings.input.group=spring-cloud-strema-group
# 配置rocketMQ
spring.cloud.stream.rocketmq.binder.name-server=192.168.150.102:9876

启动类上添加注解

@EnableBinding(Sink.class)

@EnableBinding(Sink.class) 指向配置⽂件的input参数

编写消费者程序

@Component
public class MyConsumer {
​
    @StreamListener(Sink.INPUT)
    public void onMessage(String message){
        System.out.println("收到的消息:"+message);
    }
}