SpringCloud Stream整合RocketMQ

前言

SpringCloud Stream整合的时候还是有一些坑的,请保持和我使用的版本一致!前期准备好RocketMQ环境!搭建教程往期文章RocketMQ搭建!好人做到第吧,本文demo已在gitee托管

搭建项目

1.创建SpringBoot工程
在这里插入图片描述
2.添加pom依赖

 <groupId>com.tao</groupId>
    <artifactId>rocket-stream</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>rocket-stream</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.2.5.RELEASE</spring-boot.version>
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
        </dependency>

    </dependencies>

注意版本!

3.编写application.properties文件

spring.application.name=spring-cloud-stream
#客户端连接RocketMq的地址
spring.cloud.stream.rocketmq.binder.name-server=192.168.0.177:9876;192.168.0.188:9876

#生产者
spring.cloud.stream.bindings.output.destination=test-topic
spring.cloud.stream.bindings.output.content-type=text/plain
spring.cloud.stream.bindings.output.group=test-group
#消费者
spring.cloud.stream.bindings.input.destination=test-topic
spring.cloud.stream.bindings.input.content-type=text/plain
spring.cloud.stream.bindings.input.group=test-group

3.编写生产者

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

@Service
public class SenderService {
	@Autowired
    private Source source;
	
	//使用默认source发送消息
	public void send(String msg) throws Exception{
        boolean flag = source.output().send(MessageBuilder.withPayload(msg).build());
        System.out.println("使用默认source消息发送==>"+flag );
    }
}

4.编写消费者

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.stereotype.Service;

@Service
public class ReceiveService {

	@Autowired
    private Sink sink;
	
	@StreamListener(value = Sink.INPUT)
    public void receiveMessage(String message){
        System.out.println("接收的消息input==>"+message);
    }
}

5.编写controller

@RestController
public class SendMessageController
{
	@Autowired
    private SenderService senderService;
    @GetMapping(value = "/input")
    public String input(String msg) throws Exception {
        senderService.send(msg);
        return "ok";
    }
    
}

6.启动类添加@EnableBinding

@EnableBinding(value = {Source.class, Sink.class})

7.启动服务测试
在这里插入图片描述
在这里插入图片描述

自定义消息发送

在这里插入图片描述

1.修改application.properties文件
新增如下配置

#自定义消息1
spring.cloud.stream.bindings.output1.destination=test-topic1
spring.cloud.stream.bindings.output1.content-type=text/plain
spring.cloud.stream.bindings.output1.group=test-group1
spring.cloud.stream.bindings.input1.destination=test-topic1
spring.cloud.stream.bindings.input1.content-type=text/plain
spring.cloud.stream.bindings.input1.group=test-group1

#自定义消息2
spring.cloud.stream.bindings.output2.destination=test-topic2
spring.cloud.stream.bindings.output2.content-type=text/plain
spring.cloud.stream.bindings.output2.group=test-group2
spring.cloud.stream.bindings.input2.destination=test-topic2
spring.cloud.stream.bindings.input2.content-type=text/plain
spring.cloud.stream.bindings.input2.group=test-group2

2.创建自定义Source

public interface MySource {

 	String OUTPUT = "output1";

    @Output(MySource.OUTPUT)
    MessageChannel output1();

    String OUTPUT2 = "output2";

    @Output(MySource.OUTPUT2)
    MessageChannel output2();

}

3.创建自定义Sink

public interface MySink {

    String INPUT = "input1";

    @Input(MySink.INPUT)
    SubscribableChannel input1();

    String INPUT2 = "input2";

    @Input(MySink.INPUT2)
    SubscribableChannel input2();

}

4.消息生产者

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

@Service
public class SenderService {

    
	@Autowired
    private MySource mySource;

	public void send1(String msg) throws Exception{
        boolean flag = mySource.output1().send(MessageBuilder.withPayload(msg).build());
        System.out.println("消息发送output1==>"+flag );
    }

    public void send2(String msg) throws Exception{
        boolean flag = mySource.output2().send(MessageBuilder.withPayload(msg).build());
        System.out.println("消息发送output2==>"+flag );
    }

}

5.消息消费者监听

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.stereotype.Service;

@Service
public class ReceiveService {

	@StreamListener(value = MySink.INPUT)
    public void receiveMessage1(String message){
        System.out.println("接收的消息input1==>"+message);
    }

    @StreamListener(value = MySink.INPUT2)
    public void receiveMessage2(String message){
        System.out.println("接收的消息input2==>"+message);
    }
}

6.编写controller调用自定义消息业务

	@Autowired
    private SenderService senderService;
	
	@GetMapping(value = "/input1")
    public String input1(String msg) throws Exception {
        senderService.send1(msg);
        return "ok";
    }

    @GetMapping(value = "/input2")
    public String input2(String msg) throws Exception {
        senderService.send2(msg);
        return "ok";
    }

7.主启动类

@EnableBinding(value = {Source.class, Sink.class, MySource.class, MySink.class})

8.重启服务
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
搞定!

事务消息

1.修改application.properties文件

spring.cloud.stream.bindings.outputTX.destination=TransactionTopic
spring.cloud.stream.bindings.outputTX.content-type=text/plain
spring.cloud.stream.rocketmq.bindings.outputTX.producer.group=myTXProducerGroup
#默认事务是关闭的
spring.cloud.stream.rocketmq.bindings.outputTX.producer.transactional=true

spring.cloud.stream.bindings.inputTX.destination=TransactionTopic
spring.cloud.stream.bindings.inputTX.content-type=text/plain
spring.cloud.stream.bindings.inputTX.group=transaction-group
spring.cloud.stream.rocketmq.bindings.inputTX.consumer.broadcasting=false

2.创建自定义Source

public interface MySource {

 	String OUTPUTTX = "outputTX";

    @Output(MySource.OUTPUTTX)
    MessageChannel outputTX();

}

3.创建自定义Sink

public interface MySink {

    String INPUTTX = "inputTX";

    @Input(MySink.INPUTTX)
    SubscribableChannel inputTX();

}

4.事务监听

import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.messaging.Message;

//myTXProducerGroup和properties中的配置producer.group的值一样
@RocketMQTransactionListener(txProducerGroup = "myTXProducerGroup",corePoolSize = 5,maximumPoolSize = 10)
public class TransactionListenerImpl implements RocketMQLocalTransactionListener {

    /**
    * @description: 执行本地事务,也是执行本地业务逻辑
    * @author TAO
    * @date 2021/1/19 18:35
    */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        Object num = msg.getHeaders().get("test");
        if ("1".equals(num)){
            System.out.println("executer:"+new String((byte[]) msg.getPayload())+"unknown");
            return RocketMQLocalTransactionState.UNKNOWN;
        }else if("2".equals(num)){
            System.out.println("executer:"+new String((byte[]) msg.getPayload())+"rollback");
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        System.out.println("executer:"+new String((byte[]) msg.getPayload())+"commit");
        return RocketMQLocalTransactionState.COMMIT;
    }

    /**
   * @description: 回调检查
   * @author TAO
   * @date 2021/1/19 18:34
   */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {

        System.out.println("check:"+new String((byte[]) msg.getPayload()));
        return RocketMQLocalTransactionState.COMMIT;
    }
}

5.消息生产者

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.MimeTypeUtils;

@Service
public class SenderService {

	@Autowired
    private MySource mySource;
	
	public <T> void sendTransactionalMsg(T msg,int num){
        MessageBuilder builder = MessageBuilder.withPayload(msg)
                .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
                .setHeader("test", String.valueOf(num));
        Message message=builder.build();
        mySource.outputTX().send(message);
    }
}

6.消息消费者

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;

import org.springframework.stereotype.Service;

@Service
public class ReceiveService {

	@StreamListener(value = MySink.INPUTTX)
    public void receiveMessageTX(String message){
        System.out.println("接收的消息inputTX==>"+message);
    }


}

7.controller

	@Autowired
    private SenderService senderService;
	
	@GetMapping(value = "/inputTX")
    public String inputTX(String msg) throws Exception {
        senderService.sendTransactionalMsg(msg+"1",1);
        senderService.sendTransactionalMsg(msg+"2",2);
        senderService.sendTransactionalMsg(msg+"3",3);
        senderService.sendTransactionalMsg(msg+"4",4);
        return "ok";
    }

8.重启服务器测试
在这里插入图片描述

发送标签消息

配置不用加了直接使用已存在的Source、Sink信道发送和接收消息!

1.消息生产者


import org.apache.rocketmq.common.message.MessageConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.MimeTypeUtils;

@Service
public class SenderService {

	@Autowired
    private MySource mySource;

	public <T> void sendObject(T msg,String tag) throws Exception{
        Message message=MessageBuilder.withPayload(msg)
                .setHeader(MessageConst.PROPERTY_TAGS, tag)
                .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
                .build();

        boolean flag = mySource.output2().send(message);
        System.out.println("sendObject==>"+flag );
    }
}

消息接收者就不用写了,上面案例中已经写了receiveMessage2

2.编写controller

	@GetMapping(value = "/sendObject")
    public String sendObject() throws Exception {
        JSONObject ss = new JSONObject();
        ss.put("name", "TAO");
        senderService.sendObject(ss,"myTag");
        return "ok";
    }

3.重启服务器测试
在这里插入图片描述

这里消费者监听的时候也可以根据TAG标签选择性的接收消息!在application.properties文件中添加下面配置,即可添加消息消费者限制!

spring.cloud.stream.rocketmq.bindings.input2.consumer.tags=myTag

完整配置如下图!
在这里插入图片描述
那么此消费者信道就只能监听tag为myTag的消息

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Spring Cloud StreamSpring Cloud 生态系统中的一部分,它提供了一种简单且可扩展的方式来构建消息驱动的微服务应用程序。而 RocketMQ 是一款开源的分布式消息中间件,它具有高可靠、高吞吐量、高可扩展性等特点。在 Spring Cloud Stream 中,我们可以通过集成 RocketMQ 来实现消息驱动的微服务应用程序。 下面是 Spring Cloud Stream 集成 RocketMQ 的详细文档: 1. 添加依赖 首先,我们需要添加 Spring Cloud StreamRocketMQ 的相关依赖。在 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rocketmq</artifactId> </dependency> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> ``` 2. 配置 RocketMQ 在 application.properties 文件中添加 RocketMQ 的相关配置,例如: ``` spring.cloud.stream.rocketmq.binder.namesrv-addr=127.0.0.1:9876 spring.cloud.stream.rocketmq.binder.group=rocketmq-group rocketmq.name-server=127.0.0.1:9876 rocketmq.producer.group=rocketmq-producer-group rocketmq.consumer.group=rocketmq-consumer-group ``` 3. 定义消息通道 在 Spring Cloud Stream 中,消息是通过消息通道来传递的。我们需要定义输入通道和输出通道,例如: ``` public interface MyChannel { String INPUT = "my_input"; String OUTPUT = "my_output"; @Input(INPUT) SubscribableChannel input(); @Output(OUTPUT) MessageChannel output(); } ``` 4. 发送消息 我们可以通过注入 MessageChannel 来发送消息,例如: ``` @Autowired @Qualifier(MyChannel.OUTPUT) private MessageChannel myOutput; public void sendMessage(String message) { myOutput.send(MessageBuilder.withPayload(message).build()); } ``` 5. 接收消息 我们可以通过注入 SubscribableChannel 来接收消息,例如: ``` @StreamListener(MyChannel.INPUT) public void handleMessage(Message<String> message) { log.info("Received message: {}", message.getPayload()); } ``` 6. 集成 RocketMQ 消费者 我们也可以通过集成 RocketMQ 的消费者来接收消息,例如: ``` @Slf4j @Component @RocketMQMessageListener(consumerGroup = "${rocketmq.consumer.group}", topic = MyChannel.INPUT) public class MyRocketMQConsumer implements RocketMQListener<String> { @Override public void onMessage(String message) { log.info("Received message: {}", message); } } ``` 7. 集成 RocketMQ 生产者 我们也可以通过集成 RocketMQ 的生产者来发送消息,例如: ``` @Slf4j @Component public class MyRocketMQProducer { @Autowired private RocketMQTemplate rocketMQTemplate; public void sendMessage(String message) { rocketMQTemplate.convertAndSend(MyChannel.OUTPUT, message); } } ``` 以上就是 Spring Cloud Stream 集成 RocketMQ 的详细文档。通过这种方式,我们可以快速构建消息驱动的微服务应用程序,并且具有高可靠、高吞吐量、高可扩展性等特点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员劝退师-TAO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值