处理Spring-Boot-RabbitMQ中的连接

时间:2016-07-01 09:38:25

标签: spring-amqp spring-rabbitmq spring-rabbit

您好我正在开发Spring-boot-RabbitMQ 1.6版。我在开发应用程序时遇到的问题很少。阅读文档并浏览其他堆栈溢出问题,但我无法清楚地知道一些事情(可能是因为我的记忆力不好)。 如果有人回答我的问题,那就太好了。

1)目前我有4个制作人和4个消费者。制作人可能会产生数百万个消息或事件,因此对于制作人和制作人都使用单一连接。消费者会阻止消费者消费这些消息。所以我认为是为生产者和消费者创建单独的连接,这样两者都不会阻塞,并且会提高性能。我对这种方法是否正确?

2)我正在使用 CachingConnectionFactory 来使用 SimpleRabbitListenerContainerFactory 创建连接。在调用此工厂时是否会为我们返回新连接?所以如果我们使用 CachingConnectionFactory 我们真的需要为Producer和amp;编写一个单独的连接工厂吗?消费者。请在下面找到我的

1)配置类

@Configuration
@EnableRabbit
public class RabbitMqConfiguration{

@Autowired
private CachingConnectionFactory cachingConnectionFactory;

@Value("${concurrent.consumers}")
public int concurrent_consumers;

@Value("${max.concurrent.consumers}")
public int max_concurrent_consumers;

 @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(cachingConnectionFactory);
        factory.setConcurrentConsumers(concurrent_consumers);
        factory.setMaxConcurrentConsumers(max_concurrent_consumers);
        factory.setMessageConverter(jsonMessageConverter());
        return factory;
    }

@Bean
public MessageConverter jsonMessageConverter()
{
    final Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
    return converter;
}

}

2)制作人类

@Configuration
public class TaskProducerConfiguration extends RabbitMqConfiguration {

@Value("${queue1}")
public String queue1;

@Value("${queue2}")
public String queue2;

@Value("${queue3}")
public String queue1;

@Value("${queue4}")
public String queue2;

@Value("${spring.rabbit.exchange}")
public String exchange;

@Autowired
private CachingConnectionFactory cachingConnectionFactory;

@Primary
@Bean
public RabbitTemplate getQueue1Template()
{
    RabbitTemplate template = new RabbitTemplate(cachingConnectionFactory);
    template.setRoutingKey(this.queue1);
    template.setMessageConverter(jsonMessageConverter());
    return template;
}

@Bean
public RabbitTemplate getQueue2Template()
{
    RabbitTemplate template = new RabbitTemplate(cachingConnectionFactory);
    template.setRoutingKey(this.queue2);
    template.setMessageConverter(jsonMessageConverter());
    return template;
}

@Bean
public RabbitTemplate getQueue3Template()
{
    RabbitTemplate template = new RabbitTemplate(cachingConnectionFactory);
    template.setRoutingKey(this.queue3);
    template.setMessageConverter(jsonMessageConverter());
    return template;
}

@Bean
public RabbitTemplate getQueue4Template()
{
    RabbitTemplate template = new RabbitTemplate(cachingConnectionFactory);
    template.setRoutingKey(this.queue4);
    template.setMessageConverter(jsonMessageConverter());
    return template;
}
@Bean(name="queue1Bean")
public Queue queue1()
{
    return new Queue(this.queue1);
}

@Bean(name="queue2Bean")
public Queue queue2()
{
    return new Queue(this.queue2);
}

@Bean(name="queue3Bean")
public Queue queue3()
{
    return new Queue(this.queue3);
}

@Bean(name="queue4Bean")
public Queue queue4()
{
    return new Queue(this.queue4);
}

@Bean
TopicExchange exchange() {
    return new TopicExchange(exchange);
}

@Bean
List<Binding> bindings(Queue queue1Bean,Queue queue2Bean,Queue queue3Bean,Queue queue4Bean, TopicExchange exchange) {
    List<Binding> bindingList = new ArrayList<Binding>();
    bindingList.add(BindingBuilder.bind(queue1Bean).to(exchange).with(this.queue1));
    bindingList.add(BindingBuilder.bind(queue2Bean).to(exchange).with(this.queue2));
    bindingList.add(BindingBuilder.bind(queue3Bean).to(exchange).with(this.queue3));
    bindingList.add(BindingBuilder.bind(queue4Bean).to(exchange).with(this.queue4));
    return bindingList;
}

}

3)接收器类(刚刚共享的一个接收器类,其余的3接收器类是除了队列名称和路由键之外的一个)。

@Component
public class Queue1Receiver {

@Autowired
private TaskProducer taskProducer;

@Value("${queue1}")
public String queue1;

@RabbitListener(id="queue1",containerFactory="rabbitListenerContainerFactory",queues = "#{queue1Bean}")
public void handleQueue1Message(TaskMessage taskMessage,@Header(AmqpHeaders.CONSUMER_QUEUE) String queue)
{
    System.out.println("Queue::"+queue);
    System.out.println("CustomerId: " + taskMessage.getCustomerID());
    if(taskMessage.isHasQueue2()){
        taskProducer.sendQueue2Message(taskMessage);
    }
    if(taskMessage.isHasQueue3()){
        taskProducer.sendQueue3Message(taskMessage);
    }
    if(taskMessage.isHasQueue4()){
        taskProducer.sendQueue4Message(taskMessage);
    }
}

@Bean
public Queue queue1Bean() {
    // This queue has the following properties:
    // name: my_durable,durable: true,exclusive: false,auto_delete: false
    return new Queue(queue1, true, false, false);
}

}

你的帮助应该是值得的。

注意:向下选民请在投票前注册您的评论,以便将来我可以避免错误。

根据Gary Russell的评论编辑: 1)RabbitMqConfiguration

@Configuration
@EnableRabbit
public class RabbitMqConfiguration{

@Value("${concurrent.consumers}")
public int concurrent_consumers;

@Value("${max.concurrent.consumers}")
public int max_concurrent_consumers;

 @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory());
        factory.setConcurrentConsumers(concurrent_consumers);
        factory.setMaxConcurrentConsumers(max_concurrent_consumers);
        factory.setMessageConverter(jsonMessageConverter());
        return factory;
    }

@Bean
public CachingConnectionFactory connectionFactory()
{
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
    connectionFactory.setUsername("guest");
    connectionFactory.setPassword("guest");
    connectionFactory.setCacheMode(CacheMode.CONNECTION);
    return connectionFactory;
}


@Bean
public MessageConverter jsonMessageConverter()
{
    final Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
    return converter;
}


}

2 个答案:

答案 0 :(得分:3)

  

使用单一连接生产者和消费者将阻止消费者使用消息“

是什么让你相信?单个连接通常没问题。如果您确实需要单独的连接,请将连接工厂cacheMode更改为CONNECTION

答案 1 :(得分:0)

您可以在相同的情况下使用连接池,保持池大小合适可以解决问题。如上面的回答所示,生产者和消费者都使用相同的连接,因此池可能会帮助您。