简体   繁体   English

Spring Cloud Stream RabbitMQ

[英]Spring Cloud Stream RabbitMQ

I am trying to understand why I would want to use Spring cloud stream with RabbitMQ. 我试图理解为什么我要将Rabbit云流与RabbitMQ一起使用。 I've had a look at the RabbitMQ Spring tutorial 4 ( https://www.rabbitmq.com/tutorials/tutorial-four-spring-amqp.html ) which is basically what I want to do. 我已经看过RabbitMQ Spring教程4( https://www.rabbitmq.com/tutorials/tutorial-four-spring-amqp.html ),这基本上就是我想要做的。 It creates a direct exchange with 2 queues attached and depending on the routing key a message is either routed to Q1 or to Q2. 它创建了一个直接交换,连接了2个队列,根据路由密钥,消息被路由到Q1或Q2。

The whole process is pretty straight forward if you look at the tutorial, you create all the parts, bind them together and youre ready to go. 如果您查看教程,创建所有部件,将它们绑定在一起并准备就绪,整个过程非常简单。

I was wondering what benefit I would gain in using Sing Cloud Stream and if that is even the use case for it. 我想知道使用Sing Cloud Stream会有什么好处,如果这甚至是它的用例。 It was easy to create a simple exchange and even defining destination and group was straight forward with stream. 很容易创建一个简单的交换,甚至定义目的地和组是直接的流。 So I thought why not go further and try to handle the tutorial case with stream. 所以我想为什么不进一步尝试用流处理教程案例。

I have seen that Stream has a BinderAwareChannelResolver which seems to do the same thing. 我已经看到Stream有一个BinderAwareChannelResolver ,它似乎做同样的事情。 But I am struggling to put it all together to achieve the same as in the RabbitMQ Spring tutorial. 但我正在努力将它们放在一起,以实现与RabbitMQ Spring教程相同的功能。 I am not sure if it is a dependency issue, but I seem to misunderstand something fundamentally here, I thought something like: 我不确定它是否是一个依赖问题,但我似乎在这里从根本上误解了一些东西,我想到的是:

spring.cloud.stream.bindings.output.destination=myDestination
spring.cloud.stream.bindings.output.group=consumerGroup
spring.cloud.stream.rabbit.bindings.output.producer.routing-key-expression='key'

should to the trick. 应该诀窍。

Is there anyone with a minimal example for a source and sink which basically creates a direct exchange, binds 2 queues to it and depending on routing key routes to either one of those 2 queues like in https://www.rabbitmq.com/tutorials/tutorial-four-spring-amqp.html ? 是否有任何人拥有源和接收器的最小示例基本上创建直接交换,绑定2个队列,并依赖于路由关键路由到这两个队列中的任何一个,如https://www.rabbitmq.com/tutorials /tutorial-four-spring-amqp.html

EDIT : 编辑

Below is a minimal set of code which demonstrates how to do what I asked. 下面是一组最小的代码,演示了如何执行我的要求。 I did not attach the build.gradle as it is straight forward (but if anyone is interested, let me know) 我没有附加build.gradle因为它是直接的(但如果有人有兴趣,请告诉我)

application.properties : setup the producer application.properties :设置生产者

spring.cloud.stream.bindings.output.destination=tut.direct
spring.cloud.stream.rabbit.bindings.output.producer.exchangeType=direct
spring.cloud.stream.rabbit.bindings.output.producer.routing-key-expression=headers.type

Sources.class : setup the producers channel Sources.class :设置生产者渠道

public interface Sources {

    String OUTPUT = "output";

    @Output(Sources.OUTPUT)
    MessageChannel output();
}

StatusController.class : Respond to rest calls and send message with specific routing keys StatusController.class :响应休息调用并使用特定路由键发送消息

/**
 * Status endpoint for the health-check service.
 */
@RestController
@EnableBinding(Sources.class)
public class StatusController {

    private int index;

    private int count;

    private final String[] keys = {"orange", "black", "green"};

    private Sources sources;

    private StatusService status;

    @Autowired
    public StatusController(Sources sources, StatusService status) {
        this.sources = sources;
        this.status = status;
    }

    /**
     * Service available, service returns "OK"'.
     * @return The Status of the service.
     */
    @RequestMapping("/status")
    public String status() {
        String status = this.status.getStatus();

        StringBuilder builder = new StringBuilder("Hello to ");
        if (++this.index == 3) {
            this.index = 0;
        }
        String key = keys[this.index];
        builder.append(key).append(' ');
        builder.append(Integer.toString(++this.count));
        String payload = builder.toString();
        log.info(payload);

        // add kv pair - routingkeyexpression (which matches 'type') will then evaluate
        // and add the value as routing key
        Message<String> msg = new GenericMessage<>(payload, Collections.singletonMap("type", key));
        sources.output().send(msg);

        // return rest call
        return status;
    }
}

consumer side of things, properties: 消费者方面的东西,属性:

spring.cloud.stream.bindings.input.destination=tut.direct
spring.cloud.stream.rabbit.bindings.input.consumer.exchangeType=direct
spring.cloud.stream.rabbit.bindings.input.consumer.bindingRoutingKey=orange
spring.cloud.stream.bindings.inputer.destination=tut.direct
spring.cloud.stream.rabbit.bindings.inputer.consumer.exchangeType=direct
spring.cloud.stream.rabbit.bindings.inputer.consumer.bindingRoutingKey=black

Sinks.class : Sinks.class

public interface Sinks {

    String INPUT = "input";

    @Input(Sinks.INPUT)
    SubscribableChannel input();

    String INPUTER = "inputer";

    @Input(Sinks.INPUTER)
    SubscribableChannel inputer();
}

ReceiveStatus.class : Receive the status: ReceiveStatus.class :接收状态:

@EnableBinding(Sinks.class)
public class ReceiveStatus {
    @StreamListener(Sinks.INPUT)
    public void receiveStatusOrange(String msg) {
       log.info("I received a message. It was orange number: {}", msg);
    }

    @StreamListener(Sinks.INPUTER)
    public void receiveStatusBlack(String msg) {
        log.info("I received a message. It was black number: {}", msg);
    }
}

Spring Cloud Stream lets you develop event driven micro service applications by enabling the applications to connect (via @EnableBinding ) to the external messaging systems using the Spring Cloud Stream Binder implementations (Kafka, RabbitMQ, JMS binders etc.,). Spring Cloud Stream允许您使用Spring Cloud Stream Binder实现(Kafka,RabbitMQ,JMS绑定器等)将应用程序连接(通过@EnableBinding )到外部消息系统,从而开发事件驱动的微服务应用程序。 Apparently, Spring Cloud Stream uses Spring AMQP for the RabbitMQ binder implementation. 显然,Spring Cloud Stream使用Spring AMQP进行RabbitMQ绑定器实现。

The BinderAwareChannelResolver is applicable for dynamically binding support for the producers and I think in your case it is about configuring the exchanges and binding of consumers to that exchange. BinderAwareChannelResolver适用于动态绑定对生产者的支持,我认为在您的情况下,它是关于配置消费者与该交换的交换和绑定。

For instance, you need to have 2 consumers with the appropriate bindingRoutingKey set based on your criteria and a single producer with the properties(routing-key-expression, destination) you mentioned above (except the group). 例如,您需要让2个使用者根据您的条件设置相应的bindingRoutingKey并使用上面提到的属性(routing-key-expression,destination)的单个生成器(组除外)。 I noticed that you have configured group for the outbound channel. 我注意到您已为出站通道配置了group The group property is applicable only for the consumers (hence inbound). group属性仅适用于消费者(因此是入站)。

You might also want to check this one: https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit/issues/57 as I see some discussion around using routing-key-expression . 您可能还想查看这个: https//github.com/spring-cloud/spring-cloud-stream-binder-rabbit/issues/57,因为我看到有关使用routing-key-expression一些讨论。 Specifically, check this one on using the expression value. 具体来说,使用表达式值检查一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM