springcloud -stream消息驱动(去差异化 >>目前只支持rabbitmq and kafka) 此处使用rabbitmq用作实例子

生产者 核心依赖

         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
         </dependency>

yml配置文件

 server:
   port: 8801
 ​
 spring:
   application:
     name: cloud-stream-provider
   cloud:
       stream:
         binders: # 在此处配置要绑定的rabbitmq的服务信息;
           defaultRabbit: # 表示定义的名称,用于于binding整合
             type: rabbit # 消息组件类型
             environment: # 设置rabbitmq的相关的环境配置
               spring:
                 rabbitmq:
                   host: localhost
                   port: 5672
                   username: guest
                   password: guest
         bindings: # 服务的整合处理
           output: # 这个名字是一个通道的名称  表示这是一个生产者写入信息
             destination: studyExchange # 表示要使用的Exchange(相当于一个邮箱具有存取功能,订阅才能拿到信息)名称定义
             content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
             binder: defaultRabbit # 设置要绑定的消息服务的具体设置
 ​
 eureka:
   client: # 客户端进行Eureka注册的配置
     service-url:
       defaultZone: http://localhost:7001/eureka
   instance:
     lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
     lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
     instance-id: send-8801.com  # 在信息列表时显示主机名称
     prefer-ip-address: true     # 访问的路径变为IP地址
 ​

service

 public interface IMessageProvider
 {
     public String send() ;
 }
 ​

serviceImpl

 @EnableBinding(Source.class) // 可以理解为是一个消息的发送管道的定义
 public class MessageProviderImpl implements IMessageProvider
 {
     @Resource
     private MessageChannel output; // 消息的发送管道
 ​
     @Override
     public String send()
     {
         String serial = UUID.randomUUID().toString();
         this.output.send(MessageBuilder.withPayload(serial).build()); // 创建并发送消息
         System.out.println("***serial: "+serial);
 ​
         return serial;
     }
 }

controller

 @RestController
 public class SendMessageController
 {
     @Resource
     private IMessageProvider messageProvider;
 ​
     @GetMapping(value = "/sendMessage")
     public String sendMessage()
     {
         return messageProvider.send();
     }
 }

消费者 导入与消费者相同的依赖 yaml

 server:
   port: 8802
 ​
 spring:
   application:
     name: cloud-stream-consumer
   cloud:
       stream:
         binders: # 在此处配置要绑定的rabbitmq的服务信息;
           defaultRabbit: # 表示定义的名称,用于于binding整合
             type: rabbit # 消息组件类型
             environment: # 设置rabbitmq的相关的环境配置
               spring:
                 rabbitmq:
                   host: localhost
                   port: 5672
                   username: guest
                   password: guest
         bindings: # 服务的整合处理
           input: # 这个名字是一个通道的名称  此处和生产者不同,表示一个消费者
             destination: studyExchange # 表示要使用的Exchange名称定义
             content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain”
             binder: defaultRabbit # 设置要绑定的消息服务的具体设置
            group: groupA  # 表示分组,不同分组对消息的消费方式不同
 eureka:
   client: # 客户端进行Eureka注册的配置
     service-url:
       defaultZone: http://localhost:7001/eureka
   instance:
     lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
     lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
     instance-id: receive-8802.com  # 在信息列表时显示主机名称
     prefer-ip-address: true     # 访问的路径变为IP地址

业务类

 @Component
 @EnableBinding(Sink.class)
 public class ReceiveMessageListener
 {
     @Value("${server.port}")
     private String serverPort;
 ​
     @StreamListener(Sink.INPUT)
     public void input(Message<String> message)
     {
         System.out.println("消费者1号,------->接收到的消息:" + message.getPayload()+"\t port: "+serverPort);
     }
 }

默认为不同group名称,每一个消费者都能够消费相同的信息,就会出现消息重复消费的问题 当我们使用group对消费者进行分组后,如果是相同组名,就会解决消息重复消费的问题,同组内的消息消费就变成了竞争关系,a消费的消息b就不能消费,默认采用轮询的方式进行消息的消费,也就是一人获取一次消息进行消费

posted on 2023-07-09 00:00  你就学个JVAV?  阅读(27)  评论(0)    收藏  举报

导航