【九】 Spring Cloud Stream消息驱动组件

Spring Cloud Stream 是个构建消息驱动微服务的框架。应程序通过inputs(相当于消息消费者consumer)或者outputs(相当于消息生产者producer来与Spring Cloud Stream中的binder对象交互,Binder对象是⽤来屏蔽底层MQ细节的,它负责与具体的消息中间件交互。

解决痛点问题

MQ消息中间件⼴泛应⽤在应⽤解耦合、异步消息处理、流量削峰等场景中。
不同的MQ消息中间件内部机制包括使用方式都会有所不同,比如RabbitMQ中有Exchange(交换机/交换器)这⼀概念,kafka有Topic、Partition分区这些概念,MQ消息中间件的差异性不利于我们上层的开发应用,当我们的系统希望从原有的RabbitMQ切换到Kafka时,我们会发现比较困难,很多要操作可能重来(因为应⽤程序和具体的某⼀款MQ消息中间件耦合在⼀起了)。
Spring Cloud Stream进行了很好的上层抽象,可以让我们与具体消息中间件解耦合,屏蔽掉了底层具体MQ消息中间件的细节差异,就像Hibernate屏蔽掉了具体数据库(Mysql/Oracle⼀样)。如此⼀
来,我们学习、开发、维护MQ都会变得轻松。目前Spring Cloud Stream⽀持RabbitMQ和Kafka。

概念

inputs:(相当于消息消费者consumer)
outputs:(相当于消息⽣产者producer)
Binder绑定器: 通过它来屏蔽底层不同MQ消息中间件
的细节差异,当需要更换为其他消息中间件时,我们需要做的就是更换对应的Binder绑定器⽽不需要修改任何应⽤逻辑
架构图
在这里插入图片描述

Stream编程注解

注解描述
@Input(在消费者工程中使用)注解标识输⼊通道,通过该输⼊通道接收到的消息进入应用程序
@Output(在生产者工程中使用)注解标识输出通道,发布的消息将通过该通道离开应⽤程序
@StreamListener(在消费者⼯程中使用,监听message的到来)监听队列,用于消费者的队列的消息的接收(有消息监听…)
@EnableBinding把Channel和Exchange(对于RabbitMQ)绑定在⼀起

构建服务

生产者服务

在这里插入图片描述

  1. 在lagou_parent下新建⼦module:m-cloud-stream-producer-9090
  2. pom.xml中添加依赖
         <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
     </dependency>

  1. application.yml添加配置
server:
  port: 9090

spring:
  application:
    name: m-cloud-stream-producer
  cloud:
    stream:
      binders:  # 绑定MQ服务信息(此处我们是RabbitMQ)
        mRabbitMQbinder: # 给Binder定义的名称,⽤于后⾯的关联
          type: rabbit
          environment:  # MQ环境配置(⽤户名、密码等)
            spring:
              rabbitmq:
                host: 127.0.0.1
                username: guest
                password: guest
      bindings: # 关联整合通道和binder对象
       output: # output是我们定义的通道名称,此处不能乱改
         destination: m-cloud-stream-producer-exchange
         content-type: text/plain
         binder: mRabbitMQbinder


#注册发现
eureka:
  client:
    service-url:
      defaultZone: http://CloudEurekaServerA:8761/eureka,http://CloudEurekaServerB:8762/eureka
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@

  1. 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class MCloudStreamProducer9090 {
    public static void main(String[] args) {
        SpringApplication.run(MCloudStreamProducer9090.class, args);
    }
}
  1. service
public interface IMessageProducer {

    public void sendMessage(String content);
}

@EnableBinding(Source.class)
public class IMessageProducerImpl implements IMessageProducer {
    @Autowired
    private Source source;

    @Override
    public void sendMessage(String content) {
        source.output().send(MessageBuilder.withPayload(content).build());
    }
}
  1. 测试类
@SpringBootTest(classes = {MCloudStreamProducer9090.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class MCloudStreamProducer9090Test {
    @Autowired
    private IMessageProducer iMessageProducer;

    @Test
    public void testSendMessage() {
        iMessageProducer.sendMessage("hello world");
    }
}

消费者服务

  1. 在lagou_parent下新建⼦module:m-cloud-stream-consumer-9091
  2. pom.xml中添加依赖
         <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
     </dependency>

  1. application.yml添加配置
server:
  port: 9091

spring:
  application:
    name: m-cloud-stream-consumer
  cloud:
    stream:
      binders:  # 绑定MQ服务信息(此处我们是RabbitMQ)
        mRabbitMQbinder: # 给Binder定义的名称,⽤于后⾯的关联
          type: rabbit
          environment:  # MQ环境配置(⽤户名、密码等)
            spring:
              rabbitmq:
                host: 127.0.0.1
                username: guest
                password: guest
      bindings: # 关联整合通道和binder对象
        input: # output是我们定义的通道名称,此处不能乱改
          destination: m-cloud-stream-producer-exchange
          content-type: text/plain
          binder: mRabbitMQbinder
          group: rabbit-a


#注册发现
eureka:
  client:
    service-url:
      defaultZone: http://CloudEurekaServerA:8761/eureka,http://CloudEurekaServerB:8762/eureka
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@


  1. 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class McloudSteamConsumer9091 {
    public static void main(String[] args) {
        SpringApplication.run(McloudSteamConsumer9091.class, args);
    }
}
  1. service
@EnableBinding(Sink.class)
public class MessageConsumerService {

    @StreamListener(Sink.INPUT)
    public void  receMessage(Message<String> message){
        System.out.println("=========接收到的消息:" + message);
    }
}

  • copy m-cloud-stream-consumer-9091 构建 m-cloud-stream-consumer-9092

验证

  • 生产者发送消息,消费者接收
    在这里插入图片描述
  • 同组内消息不会重复消费(启动m-cloud-stream-consumer-9092)
    在这里插入图片描述
    在这里插入图片描述

Stream⾼级之自定义消息通道

Stream 内置了两种接⼝Source和Sink分别定义了 binding 为 “input” 的输⼊流和 “output” 的输出流,
我们也可以自定义各种输⼊输出流(通道),但实际我们可以在我们的服务中使⽤多个binder、多个输入通道和输出通道,然⽽默认就带了⼀个input的输⼊通道和⼀个output的输出通道,怎么办?我们是可以自定义消息通道的,学着Source和Sink的样⼦,给你的通道定义个自己的名字,多个输⼊通道和输出通道是可以写在⼀个类中的

  • 定义接口
interface CustomChannel {
 String INPUT_LOG = "inputLog";
 String OUTPUT_LOG = "outputLog";
 
 @Input(INPUT_LOG)
 SubscribableChannel inputLog();
 
 @Output(OUTPUT_LOG)
 MessageChannel outputLog();
}
  • @EnableBinding 注解中,绑定自定义的接口
  • 使⽤ @StreamListener 做监听的时候,需要指定 CustomChannel.INPUT_LOG
bindings:
 inputLog:
 destination: mmExchange
 outputLog:
 destination: eduExchange
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

刚仔灬

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

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

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

打赏作者

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

抵扣说明:

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

余额充值