spring cloud stream

创建spring boot工程,添加pom依赖

复制代码
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
View Code
复制代码

添加消息接收SinkReceiver

复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;

@EnableBinding(Sink.class)
public class SinkReceiver {
    private static Logger logger= LoggerFactory.getLogger(SinkReceiver.class);
    @StreamListener(Sink.INPUT)
    public void receive(Object payload){
        logger.info("Received: "+payload);
    }
}
View Code
复制代码

配置

复制代码
spring.application.name=stream-hello

spring.rabbitmq.host=10.202.203.29
spring.rabbitmq.port=5672
spring.rabbitmq.username=springcloud
spring.rabbitmq.password=123456
View Code
复制代码

运行程序,打开rabbitmq监控界面,可以看到

推送消息

在控制台查看结果

 

创建一个消息发送类SinkSender

复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.InboundChannelAdapter;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.core.MessageSource;
import org.springframework.messaging.support.GenericMessage;

import java.util.Date;

@EnableBinding(value = {Sink.class})
public class SinkSender {
    private static Logger logger= LoggerFactory.getLogger(SinkSender.class);
    @Bean
    @InboundChannelAdapter(value = Sink.INPUT,poller = @Poller(fixedDelay = "2000"))
    public MessageSource<Date> timerMessageSource(){
        return ()-> new GenericMessage<>(new Date());
    }
}
View Code
复制代码

启动工程,可以在控制台看到每隔2秒收到信息

 

在SinkSender中添加日期转换

复制代码
    @Transformer(inputChannel = Sink.INPUT,outputChannel = Sink.INPUT)
    public Object transform(Date message){
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(message);
    }
View Code
复制代码

控制台查看消息

 

添加一个User类

复制代码
public class User {
    private Integer id;
    private String name;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
View Code
复制代码

修改SinkSender

复制代码
@Bean
    @InboundChannelAdapter(value = Sink.INPUT,poller = @Poller(fixedDelay = "2000"))
    public MessageSource<String> timerMessageSource(){
        return ()->new GenericMessage<>("{\"id\":1,\"name\":\"tom\",\"age\":20}");
    }
View Code
复制代码

修改SinkReceiver

复制代码
@ServiceActivator(inputChannel = Sink.INPUT)
    public void receive(User user){
        logger.info("Received: "+user);
    }
    @Transformer(inputChannel = Sink.INPUT,outputChannel = Sink.INPUT)
    public User transform(String message) throws Exception {
        ObjectMapper objectMapper=new ObjectMapper();
        User user=objectMapper.readValue(message,User.class);
        return user;
    }
View Code
复制代码

这里使用@ServiceActivator必须指定@Transformer来处理自定义对象

改成就无需自定义@Transformer

复制代码
@StreamListener(Sink.INPUT)
    public void receive(User user){
        logger.info("Received: "+user);
    }
View Code
复制代码

 

消息反馈

按上面项目再新建两个项目:App1和App2

App1

复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.messaging.handler.annotation.SendTo;

@EnableBinding(value = {Processor.class})
public class App1 {
    private static Logger logger= LoggerFactory.getLogger(App1.class);
    @StreamListener(Processor.INPUT)
    @SendTo(Processor.OUTPUT)
    public Object receiveFromInput(Object payload){
        logger.info("Received: "+payload);
        return "From Input Channel Return - "+payload;
    }
}
View Code
复制代码

App2

复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.InboundChannelAdapter;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.core.MessageSource;
import org.springframework.messaging.support.GenericMessage;

import java.util.Date;

@EnableBinding(value = {Processor.class})
public class App2 {
    private static Logger logger= LoggerFactory.getLogger(App2.class);
    @Bean
    @InboundChannelAdapter(value = Processor.OUTPUT,poller = @Poller(fixedDelay = "2000"))
    public MessageSource<Date> timeMessageSource(){
        return ()->new GenericMessage<>(new Date());
    }
    @StreamListener(Processor.INPUT)
    public void receiveFromOutput(Object payload){
        logger.info("Received: "+payload);
    }
}
View Code
复制代码

App2的配置做个变更

复制代码
spring.rabbitmq.host=10.202.203.29
spring.rabbitmq.port=5672
spring.rabbitmq.username=springcloud
spring.rabbitmq.password=123456

spring.cloud.stream.bindings.input.destination=output
spring.cloud.stream.bindings.output.destination=input

server.port=8001
View Code
复制代码

启动两个项目

 

消费组

启动多个消费端App1和一个生产端App2,可以看到App2发送的消息被多个App1接收并处理

通过指定group可以然消息只被相应的group接收

App1-1

spring.cloud.stream.bindings.input.group=Service-A

App1-2

spring.cloud.stream.bindings.input.group=Service-A

App2

spring.cloud.stream.bindings.input.group=Service-A

这样App2发送的消息将被两个App1轮询处理

如果此时添加一个App1-3

spring.cloud.stream.bindings.input.group=Service-B

 

 从rabbitmq管理界面查看

 

一个exchange绑定了两个queue,从exchange里推送一条消息,两个queue里都会有

posted @   uptothesky  阅读(311)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
点击右上角即可分享
微信分享提示