【8.基于Spring Cloud的消息驱动框架Stream】

注:本人所有的spring-cloud系列的文章均为黑马的《Spring Cloud微服务架构开发》的个人笔记。

基于Spring Cloud的消息驱动框架Stream

  • 了解Spring Cloud Stream的基本概念
  • 熟悉Spring Cloud Stream 与RabbitMQ结合使用
  • 熟悉Stream的发布-订阅模式的概念
  • 熟悉Stream的消费组与消息分区的使用

作用:使用Spring Cloud Stream整合消息中间件降低系统和中间件的耦合性;是spring cloud对于消息中间件的进一步封装;使用其可忽略消息中间件之间的差异,有效降低开发人员对消息中间件的使用复杂度。
;目前支持的消息中间件只有RabbitMQ和Kafka

Spring Cloud Stream应用模型:
在这里插入图片描述

1.入门案例

首先需要在本地安装RabbitMQ,此案例通过RabbitMQ中间件接收消息并打印在控制台

1.1 创建springboot项目stream-hello

添加依赖web 、test 以及stream-rabbit

<!--该依赖用于提供Spring Cloud Stream对RabbitMQ支持-->
  <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
       <version>2.1.3.RELEASE</version>
 </dependency>

1.2 创建消息消费类rabbitmq.SinkReceiver

@EnableBinding(Sink.class)  //开启绑定通道的注解 Sink是stream组件默认的输入通道接口
public class SinkReceiver {
	private static Logger logger = LoggerFactory.getLogger(AinkReceiver.class);
	
	@StreamListener(Sink.INPUT)  //注解为监听器
	public void receiver(String payload){
		logger.info("Receiver:"+payload)
	}
}

1.3 测试

先启动RibbitMQ 再启动stream-hello
在这里插入图片描述
浏览器访问:http://localhost:15672 登录RabbitMQ图形化界面

2.Stream的发布-订阅模式

在这里插入图片描述
消息提供者发送消息到RabbitMQ,消息消费者向RabbitMQ订阅消息,消息消费者在订阅的主题中收到它并触发自身的业务逻辑处理。

2.1 创建消息提供者stream-rabbitmq-provider

pom.xml文件

<!--该依赖用于提供Spring Cloud Stream对RabbitMQ支持-->
  <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
       <version>2.1.3.RELEASE</version>
 </dependency>

application.yml

server:
	port: 8898
spring:
	application:
	  name: stream-rabbitmq-provider
	rabbitmq:   #安装到本地的mq,此节点会默认有以下值,可以不设置,通常mq单独部署在一台服务器
	  host: localhost
	  port: 5672
	  username: guest
	  password: guest
	cloud:
	  stream:
	    bindings:
	      output:
	        destination: minestream    #指定当前主题的名称 与消费者的一致

创建provider.StreamProvider类向mq发送消息

@EnableBinding(Source.class)  //source是stream组件默认输出通道接口
@RestController
public class StreamProvider {
	@Autowired
	@Otput(Source.OUTPUT)
	private MessageChannel channerl;
	@GetMapping("/send")
	public void send(){
		channel.send(MessageBuilder.withPayload("hello world").build());
	}
}

2.2 创建消息消费者stream-rabbitmq-consumer

pom.xml 同 消息提供者stream-rabbitmq-provider
application.yml

server:
	port: 9898
spring:
	application:
	  name: stream-rabbitmq-consumer
	rabbitmq:   #安装到本地的mq,此节点会默认有以下值,可以不设置,通常mq单独部署在一台服务器
	  host: localhost
	  port: 5672
	  username: guest
	  password: guest
	cloud:
	  stream:
	    bindings:
	      output:
	        destination: minestream    #指定当前主题的名称 与提供者的一致

创建consumer.StreamConsumer类订阅消息

@EnableBinding(Sink.class)  
public class StreamConsumer {
	@StreamListener(Sink.INPUT)
	public void receiver(String payload){
		System.out.println("接收到了mq中发送来的消息:"+ payload)	
	}
}

启动提供者和消费者
provider控制台:
在这里插入图片描述
consumer控制台:
在这里插入图片描述

3.Stream消费组

在实际开发中,微服务应用为了实现高可用和负载均衡,会部署多个实例。默认情况下,当消息提供者发出一条消息到绑定通道上,这条消息会被每个消费者实例接收和处理(出现了重复消费的问题)。Stream消费组即用来解决此问题
创建两个消息消费者 ,在其配置文件添加group如下代码:

spring:
	cloud:
		stream:
			bindings:
				input:
				    destination:minestream
					group: stream   # 两个消费者同

此时的mq图形化界面Queues只有一个队列
在这里插入图片描述
当访问 localhost:8898/send 的时候,只在其中一个消费者的控制台接收到消息,当再次访问 localhost:8898/send ,则在另一个消费者的控制台接收到消息,此消费者采用是是轮询法

4.消费分区

在特定情况下,mq接收到的消息需要同一个消费实例消费的时候,需要用到消费分区
在消息提供者是配置文件下添加如下参数:

spring:
  cloud:
    stream:
      bindings:
        output:
          destination: minestream
          provider:
          #分区表达式,例如当表达式的值为1.那么在订阅者的instance-index中为1的接收方,将会执行该消息
            partition-key-expression: 1
            partition-count: 2 #参与消费分区的消费者数量
      

修改消息消费者1

spring:
  cloud:
    stream:
      bindings:
        input:
          destination:minestream
          group: stream
          consumer:
            partitioned: true  # 是否开启分区
      instance-count: 2  #分区数量  对齐bindings
      instance-index:    #当前实例的索引号  对齐bindings

修改消息消费者2

spring:
  cloud:
    stream:
      bindings:
        input:
          destination:minestream
          group: stream
          consumer:
            partitioned: true  # 是否开启分区
      instance-count: 2  #分区数量  对齐bindings
      instance-index: 1  #当前实例的索引号  对齐bindings
      ######仅索引号不同

访问 localhost:8898/send 的时候 消费者2接收到消息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值