2
votes

I am having trouble grasping the knowledge of how RabbitMQ and Spring Cloud Stream work together. What i want to do is the following (Basic explanation):

I have a producer which produces messages, which are things like: SendEmail, ReceiveEmail and ErrorOccurred. These will go on the message bus. Then i have 3 consumers. A LogService an Emailservice and a ParserService.

EmailService will pick up all the Email messages, LogService will pick up the ErrorOccurred (generated by other producers too) and the EmailSend messages. Finally the ParserService will only get the ReceiveEmail messages.

I cant seem to get this configured with Spring Cloud Stream. I can send and receive a single event from one producer to one receiver, and one producer to multiple subscribers (one topic, multiple queue's but no wildcards).

spring:
  rabbitmq:
    host: localhost
    username: guest
    password: guest
  cloud:
    stream:
      bindings:
        output: # <-- Question 1
          destination: # <-- Question 2

With the standard Source.class interface binding.

And EmailService:

spring:
  rabbitmq:
    host: localhost
    username: guest
    password: guest
  cloud:
    stream:
      bindings:
        input:
          destination: # <-- Question 3

And the same for LogService as the above.

Question 1: I only defined one output, but obviously i need 2? But then i cant use "input" as channel name right? And i need to configure my own Channel names with Output("CHANNEL NAME HERE"). But what does this channel name mean? I dont see the channel name reappearing in the RabbitMQ webinterface or anything. Is this just application internal naming?

Question 2: This is the exchange name as far as i understood. If i read the docs right, i need an Topic type exchange for the Email messages as i have 3 receivers. Do i also have 3 separate queues then? But how do i configure 1 queue receives only EmailReceived, 1 queue receiving all and 1 queue the EmailSend messages?

Question 3: Do i need to make an exchange for every different event i want to send? Shouldn't i be able to subscribe to all email.* events? If i use it like that, i create a queue with that exact name and a Topic with that exact name. Which is not right, as far as i know.

I want to do it liek this, https://www.rabbitmq.com/tutorials/tutorial-five-spring-amqp.html. But the problem is, they use the basic RabbitMQ Spring AMQP and i chose to use the Spring Cloud Stream (as it is advertised as THE tool to make microservice communication atc etc).

Should i use SCS or should i use Spring-AMQP library? if so, how should i configure this? If i need to explain more, please ask for any clarification. Thanks in advance!

1

1 Answers

1
votes

On the producer side, you only need one destination; set the routingKeyExpression to route to one of 3 queues, based on something in the message (e.g. a header - routing-key-expression=headers[route]).

You can also have multiple output channels pointing to the same destination (but with a different - literal - routing key expression 'email.foo').

On the consumer side; you can use the same destination, but each consumer will have one queue bound to that exchange, side the bindingRoutingKey to, e.g., email.#.

See the documentation.