spring cloud stream rabbitMq 生产-消费模式

首先创建两个spring cloud项目,一个项目为生产者项目,一个项目为消费者项目

在两个项目中引入stream的包

这里使用的是rabbitMq的包

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

然后配置文件中添加mq相关配置

spring
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest

这时启动项目,启动日志中会出现类似以下日志,说明rabbitMq连接成功

Attempting to connect to: [127.0.0.1:5672]
Created new connection: rabbitConnectionFactory#28068327:0/SimpleConnection@55fbebba [delegate=amqp://guest@127.0.0.1:5672/, localPort= 51415]

现在在生产者项目中创建一个生产者

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;

import java.util.UUID;

@EnableBinding(Source.class)
public class Producer {
    @Autowired
    @Output(Source.OUTPUT)
    private MessageChannel channel;

    public void send() {
        channel.send(MessageBuilder.withPayload("22222222222" + UUID.randomUUID().toString()).build());
    }
}

在消费者项目中创建一个消费者

import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.messaging.Message;

@EnableBinding(Sink.class)
public class Consumer {
    @StreamListener(Sink.INPUT)
    public void receive(Message<String> message) {
        System.out.println("接收到MQ消息:" + JSONObject.toJSONString(message));
    }
}

这里我用的stream提供的接口,也可以自定义

public interface Sink {
  String INPUT = "input";

  @Input(Sink.INPUT)
  SubscribableChannel input();
}
public interface Source {
    String OUTPUT = "output";

    @Output("output")
    MessageChannel output();
}

复制以上两个类的代码并修改INPUT或者OUTPUT便可完成自定义接口

需要注意的是INPUT和OUTPUT的值会在配置文件中做配置,不然你会发现项目没报错,消息也发出去了,但是收不到,这里非常重要

官方文档也有说明

setting the application property spring.cloud.stream.bindings.input.destination to raw-sensor-data will cause it to read from the raw-sensor-data Kafka topic, or from a queue bound to the raw-sensor-data RabbitMQ exchange

在生产者项目配置文件中添加

spring
  cloud:
    stream:
      bindings:
        output:
          destination: my-test-channel

在消费者项目配置文件中添加

spring
  cloud:
    stream:
      bindings:
        input:
          destination: my-test-channel

这里的input和output分别对应上面的Sink.INPUT和Source.OUTPUT

在生产者项目中创建一个controller,将Producer自动注入,写一个get或post调用Producer.send

重启两个项目,调用Producer.send,这时消费者项目控制台会打印

接收到MQ消息:{"headers":{"amqp_receivedDeliveryMode":"PERSISTENT","amqp_receivedRoutingKey":"my-test-channel","amqp_receivedExchange":"my-test-channel","amqp_deliveryTag":1,"amqp_consumerQueue":"my-test-channel.anonymous.vYA2O6ZSQE-S9MOnE0ZoJQ","amqp_redelivered":false,"id":"805e7fc3-a046-e07a-edf5-def58d9c8eab","amqp_consumerTag":"amq.ctag-QwsmRKg5f0DGSp-7wbpYxQ","contentType":"text/plain","timestamp":1523930106483},"payload":"22222222222a7d24456-5b11-4c25-9270-876e7bbc556a"}

说明测试成功

这里还有一点需要注意,我之前没注意踩了个坑,在项目完全启动好之前,可能会存在加载顺序不一致,我在controller中自动注入了一个方法来调用Producer.send,结果项目启动失败,原因就是rabbitMq的相关配置还没完全初始化,把调用放在get请求方法中等项目启动完成就可以调用了





阅读更多
个人分类: Java
上一篇Spring boot junit 单元测试
下一篇spring boot rabbitmq 接收消息时异常死循环
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭