如何在spring boot rabbitmq中单独配置生产者和消费者?

时间:2018-03-27 10:38:01

标签: java spring-boot rabbitmq

我是Spring boot RabbitMQ的新手。我想知道如何单独配置生产者和消费者,比如他们是两个独立的实体(可能是不同的主机)。我有示例代码 -

Sender.java

package ch.keko.springamqp;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;

public class Sender {

@Autowired
private RabbitTemplate rabbitTemplate;

@Scheduled(fixedDelay = 500L)
public void send() {
    this.rabbitTemplate.convertAndSend("foo", "test queue");
}

}

SampleAmqpSimpleApplication.java

package ch.keko.springamqp;

import org.springframework.amqp.core.Queue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class SampleAmqpSimpleApplication {

@Bean
public Sender mySender() {
    return new Sender();
}


@Bean
public Listerner myListener() {
    return new Listerner();
}

@Bean
public Queue fooQueue() {
    return new Queue("foo");
}

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

}

Listener.java

package ch.keko.springamqp;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Payload;

import java.util.Date;

@RabbitListener(queues = "foo")
public class Listerner {

@RabbitHandler
public void process(@Payload String foo) {
    System.out.println(new Date() + ": " + foo);
}
}

如果我们将生产者和消费者分离为两个不同的独立实体,我想知道所需的最低配置是什么。

1 个答案:

答案 0 :(得分:0)

如果我理解你,你只需要为你正在使用的每个队列生产者/消费者类。有效载荷/消息是每个队列中的不同之处,永远不要混淆它们。

在RabbitMQ中你可以使用队列或交换,让我们说:     com.megna.queue1.in     com.megna.queue1.out

com.megna.queue2.in
com.megna.queue2.out

com.megna.queue3.in
com.megna.queue3.out

基本上com.megna.queueX适用于您的实体,而in / out适用于发送和接收。但是进出可能会有所不同,因为可能是一个完整的对象作为XML而out是回答Queue你只需发送一个OK,回答对象或Exception。在我的项目中,我有3个对象:

QueueObjectData - The Object / Message / Payload I want to process
QueueObjectAnswer - The answer of an successful processing
QueueException - Generalized Exception Class with informationen, Stacktrace etc.

Consumer queue3订阅com.megna.queue3.in,反序列化(使用)实体queue3Data,并通过为其配置的生产者发送回应答queue3Answer或QueueException,而不是自己。

在生产环境中,您会找到不同的名称,有时会请求输入和响应输出。但它们完全相同,通过MQ交换消息。

如果你有一个前端集群订阅来自queue3.out的答案以向用户显示结果,请记住MQ是FIFO,因此要为用户发回消息并不容易,你必须要考虑关于在前端或使用更多队列,即集群中的3个前端服务器需要3个队列。但实际上,这甚至是因为用户可以更改服务器并且消息永远不会被用户接收。

RabbitMQ有一个更好的系统,而不是队列,使用交换(https://www.rabbitmq.com/tutorials/tutorial-three-java.html)并订阅它们。您可以使用与上面相同的系统,但它们是交换并发送到多个队列和订阅者。如果您将后端与2台或更多台机器集中在一起,那么后端的每个消费者都会收到消息。

在这里你必须平衡整个事情。你不会是第一个因多个消费者做同样事情而获得竞争条件的人。

MQ并不是一件容易的事情,因此配置它不仅仅是一些代码行,你必须有一个负责的概念,并且基于此,你需要一个队列或一个Exchange。在上面的教程中,您将获得示例代码,但仍然需要知道您在做什么。