41、微服务 Spring Cloud Stream 消息驱动

为啥要使用 Spring Cloud Stream,在通过消息中间件的时候,可能会用RabbitMQ、kafaka、ActiveMQ,由于他们的底层是不一样的,所以在消息发送和接收有差异、不能互通,使用Stream可以解决这个问题,相当于Stream可以处理所有消息中间件发送和接收,本次使用RabbitMQ 做测试,所有要有rabbitMQ的环境

1、创建cloud-stream-rabbit-provider8801 消息生产者

编写pom.xml 添加依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

编写application.yml 配置文件

server:
  port: 8801

spring:
  application:
    name: cloud-stream-provider
  cloud:
    stream:
      binders:
        defaultRabbit:
          type: rabbit
          environment:
            spring:
              rabbitmq:
                host: 8.129.215.115
                username: rabbit
                password: 123456
                port: 5672
      bindings:
        output:   #生产者发送消息
          destination: studyExchange  #exchange名称,交换模式默认是topic
          content-type: application/json

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      # defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    instance-id: stream-provider8801
    prefer-ip-address: true
    #客户端向Eureka 发送心跳的时间间隔
    lease-renewal-interval-in-seconds: 1
    lease-expiration-duration-in-seconds: 2

编写主启动类

@SpringBootApplication
public class StreamRabbitProviderMain8801 {
    public static void main(String[] args) {
        SpringApplication.run(StreamRabbitProviderMain8801.class ,args);
    }
}

编写消息发送的接口

public interface IMessageProvider {

    public String send();
}

编写消息发送接口实现类

@EnableBinding(Source.class) //定义消息发送管道
public class MessageProviderImpl implements IMessageProvider {

    @Resource
    private MessageChannel output;
    @Override
    public String send() {

        String uuid = UUID.randomUUID().toString();
        output.send(MessageBuilder.withPayload(uuid).build());
        System.out.println("消息发送成功:" + uuid);
        return uuid;
    }
}

编写controller 发送消息请求

@RestController
public class ProviderController {
    @Resource
    private IMessageProvider iMessageProvider;

    @GetMapping(value = "/sendMessage")
    public String sendMessage() {
        String send = iMessageProvider.send();
        return send;
    }
}

测试发送消息:http://localhost:8801/sendMessage

2、创建消息消费者 cloud-stream-rabbit-consumer8802 

编写pom.xml 添加依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

编写application.yml 配置文件

server:
  port: 8802

spring:
  application:
    name: cloud-stream-consumer8802
  cloud:
    stream:
      binders:
        defaultRabbit:
          type: rabbit
          environment:
            spring:
              rabbitmq:
                host: 8.129.215.115
                username: rabbit
                password: 123456
                port: 5672
      bindings:
        input:   #消费者消费消息
          destination: studyExchange  #exchange名称,交换模式默认是topic
          content-type: application/json
          group: atguiguA   # 一定要加上,这可以解决消息重复消费,和消息的持久化

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      # defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    instance-id: stream-consumer8802
    prefer-ip-address: true
    #客户端向Eureka 发送心跳的时间间隔
    lease-renewal-interval-in-seconds: 1
    lease-expiration-duration-in-seconds: 2

编写主启动类

@SpringBootApplication
public class StreamConsumerMain8802 {

    public static void main(String[] args) {
        SpringApplication.run(StreamConsumerMain8802.class, args);
    }
}

编写controller 监听消息并消费消息

@Component
@EnableBinding(Sink.class)
public class ReveiceConsumerListenerController {

    @Value("${server.port}")
    private String serverPort;

    @StreamListener(Sink.INPUT)
    public void reveiveMessage(Message<String> message) {
        System.out.println("我是消费者1号:============》"+ message.getPayload()+ "\t"+ "serverPort: "+ serverPort);
    }
}

3、创建消息消费者 cloud-stream-rabbit-consumer8803 基本和 cloud-stream-rabbit-consumer8802 一样的配置,两个消息消费者测试重复消费的问题,和消息持久化的问题

posted @ 2021-07-02 00:02  shunnWcs  阅读(46)  评论(0)    收藏  举报