美文网首页Java
SpringCloud之stream

SpringCloud之stream

作者: TZX_0710 | 来源:发表于2019-06-21 17:24 被阅读0次

    Spring Cloud Stream 是一个构建消息驱动微服务的框架,应用程序通过input通道或者output通道来与Spring Cloud Stream中binder交互,通过配置来binding. 而Spring Cloud Stream的binder负责与中间件交互, 消息的中间件有(RabbitMQ, Kafka, ActiveMQ).
    本文以RabbitMQ作为中间件作为讲解(启动rabbitMQ: rabbitmq-plugins enable rabbitmq_management)

    Producer
    1.通过IDEA的spring init新建SpringBoot项目
    引入依赖

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

    配置yml文件

    server:
      port: 8081
    spring:
      application:
        name: producer
      cloud:
        stream:
          bindings:
            output1:
              destination: Theme-People #可以理解为一个和订阅者的通道
              group: Group-Boy
              content-type: application/json   
              producer:
                partitionKeyExpression: headers['partitionKey']
                partitionCount: 2
    

    新建一个实体类 用于发送

    package com.cloud.cloud_streaming.vo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.ToString;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class Person {
    
        private String id;
    
        private String name;
    
        private int age;
    
        private String password;
    }
    

    新建输出通道

    package com.cloud.cloud_streaming;
    import org.springframework.cloud.stream.annotation.Output;
    import org.springframework.messaging.MessageChannel;
    import org.springframework.stereotype.Component;
    
    @Component
    public interface OutputInterface {
        String OUTPUT1 = "output1";
        String OUTPUT2 = "output2";
    //创建一个输出通道  output1
        @Output(OUTPUT1)
        MessageChannel output1();
    }
    

    新建一个service用域处理发送消息

    package com.cloud.cloud_streaming;
    
    import com.cloud.cloud_streaming.vo.Person;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.messaging.MessageChannel;
    import org.springframework.messaging.support.MessageBuilder;
    import org.springframework.stereotype.Component;
    
    @Slf4j
    @Component
    public class StreamService {
    
        @Autowired
        @Qualifier(OutputInterface.OUTPUT1)
        MessageChannel channel1;
    
        public void sendMessage(String channel) {
            String message = "Send Message Manually,From Channel:" + channel;
            log.info( "Send Message from channel:" + channel );
            switch (channel) {
                case OutputInterface.OUTPUT1:
                    channel1.send( MessageBuilder.withPayload( message ).build() );
                    return;
                default:
                    log.info( "参数错误: " + channel );
                    return;
            }
        }
    }
    

    新建一个定时任务类

    package com.cloud.cloud_streaming;
    
    import com.cloud.cloud_streaming.vo.Person;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.cloud.stream.annotation.EnableBinding;
    import org.springframework.messaging.Message;
    import org.springframework.messaging.MessageChannel;
    import org.springframework.messaging.support.MessageBuilder;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    
    @Slf4j
    @EnableBinding(value = {OutputInterface.class})
    @EnableScheduling
    public class MessageSender {
    
        @Autowired
        private OutputInterface outputInterface;
    
        /**
         * 第一种方法, 没有指定output的MessageChannel, 通过OutputInterface去拿具体的Channel
         * 设置partitionKey主要是为了分区用, 可以根据根据这个partitionKey来分区
    采用定时任务去发送
         */
        @Scheduled(initialDelay = 1000, fixedRate = 5000)
        public void sendMessageMethod1() {
            Message message = MessageBuilder.withPayload( "From sendMessageMethod1" )
                    .setHeader( "partitionKey", 1 )
                    .build();
    
            outputInterface.output1().send( message );
        }
    
        /**
         * 第二种方法, 直接指定output的MessageChannel
         */
    //    @Autowired
    //    @Qualifier(OutputInterface.OUTPUT2)
    //    MessageChannel output;
    //
    //    @Scheduled(initialDelay = 2000, fixedRate = 4000)
    //    public void sendMessageMethod2() {
    //        Person p = new Person();
    //        p.setName( "Person2" );
    //        p.setAge( 1 );
    //
    //        output.send( MessageBuilder.withPayload( p )
    //                .setHeader( "partitionKey", 2 )
    //                .build() );
    //    }
    }
    

    controller层

    package com.cloud.cloud_streaming;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @Slf4j
    public class StreamController {
        @Autowired
        StreamService streamService;
    
        @GetMapping("/sendMessageByChannalName")
        public void sendMessage(String channel) {
            streamService.sendMessage( channel );
        }
    }
    

    cusomer
    1.引入依赖

     <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
    

    2.配置yml

    spring:
      application:
        name: consumer
      cloud:
        stream:
          bindings:
            input1:
              destination: Theme-Animal  #h对应的输出通道 同一个通道
              group: Group-Boy
              content-type: application/json
              consumer:
                partitioned: true #是否分区
          instance-index: 0  #用那个分区来接收消息
          instance-count: 2  #分区数
    

    输入类

    package com.tg.stream_cusomer;
    
    import org.springframework.cloud.stream.annotation.Input;
    import org.springframework.messaging.SubscribableChannel;
    import org.springframework.stereotype.Component;
    
    @Component
    public interface InputInterface {
        String INPUT1 = "input1";
    
        @Input(INPUT1)
        SubscribableChannel input1();
    }
    

    同样新建一个实体类,因为采用的是发送实体

    package com.tg.stream_cusomer;
    
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.ToString;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class Person {
        private String name;
    
        private int age;
    }
    

    接受消息的处理层

    package com.tg.stream_cusomer;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.amqp.support.AmqpHeaders;
    import org.springframework.cloud.stream.annotation.EnableBinding;
    import org.springframework.cloud.stream.annotation.StreamListener;
    import org.springframework.messaging.Message;
    import org.springframework.messaging.handler.annotation.Header;
    import org.springframework.messaging.handler.annotation.Payload;
    
    @Slf4j
    @EnableBinding(value = {InputInterface.class})
    public class MessageReceiver {
        @StreamListener(InputInterface.INPUT1)
        public void receiveMessageFromChannel1(@Payload Message <String> payload, @Header(AmqpHeaders.CONSUMER_QUEUE) String partition) {
            log.info( "ReceiveMessageFrom INPUT1, message: {}, Queue:{}", payload.getPayload(), partition );
        }
    }
    

    启动producer的project
    再启动cusomer的project

    相关文章

      网友评论

        本文标题:SpringCloud之stream

        本文链接:https://www.haomeiwen.com/subject/grhunqtx.html