从兔子mq读取非常慢

时间:2017-11-29 23:26:39

标签: spring-boot rabbitmq spring-batch spring-rabbitmq

我的作业必须从rabbitmq队列中读取并将其写入数据存储。目前我使用AmqpItemReader来读取队列中的消息。

我读取的数据是Json格式,我ItemProcessor的所有数据都是将json序列化为java对象。

我的单线程解决方案的性能非常低。我只能以每秒12毫秒的速度消耗。我将有大约1000万条记录要处理。因此,我尝试将其更改为多线程步骤,但仍然无法看到吞吐量的显着改善(每秒大约50 msgs)。

我如何加快工作速度。我开始怀疑我采取的路线是不对的。任何关于此的亮点都将受到赞赏。提前谢谢。

编辑:包含的代码/配置,以进一步明确我想要实现的目标。

Rabbit服务器配置: AWS上的3节点集群,每个集群具有0.5 Gig内存。

留言详情: 每个有效载荷大约为1千字节JSON。

我在开发机器上运行弹出批处理作业(Macintosh)。

系统配置:

  Processor Name:   Intel Core i7
  Processor Speed:  2.5 GHz
  Number of Processors: 1
  Total Number of Cores:    4
  L2 Cache (per Core):  256 KB
  L3 Cache: 6 MB
  Memory:   16 GB

我的项目阅读器:

import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.batch.item.amqp.AmqpItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class RabbitMQItemReader extends AmqpItemReader<Message> {

  private final Logger logger = LoggerFactory.getLogger(RabbitMQItemReader.class);

  @Autowired
  private final RabbitTemplate template;

  public RabbitMQItemReader(RabbitTemplate rabbitTemplate) throws IOException {
    super(rabbitTemplate);
    template = rabbitTemplate;
  }

  @Override
  public Message read() {
    return template.receive();
  }
}

我的步骤:

private Step step() throws Exception {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(100);
    executor.setMaxPoolSize(100);
    executor.setThreadNamePrefix("SThread");
    executor.setWaitForTasksToCompleteOnShutdown(true);

    executor.initialize();
    return stepBuilderFactory.get("queueToCassandraStep")
        .<Message, Vendor>chunk(100)
        .reader(itemReader)
        .listener(new QueueReaderListener<>())
        .processor(asyncItemProcessor())
        .writer(asyncItemWriter())
        .taskExecutor(executor)
        .build();
  }

Rabbit Config:

import lombok.Setter;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties("art.com.service.product.config.rabbitmq")
public class RabbitConfig {

  @Setter
  private String host;
  @Setter
  private Integer port;
  @Setter
  private String username;
  @Setter
  private String password;
  @Setter
  private String exchangeName;
  @Setter
  private String queueName;

  @Bean
  ConnectionFactory rabbitConnectionFactory() {
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host);
    connectionFactory.setPort(port);
    connectionFactory.setUsername(username);
    connectionFactory.setPassword(password);
    return connectionFactory;
  }

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

  @Bean
  RabbitTemplate rabbitTemplate(ConnectionFactory rabbitConnectionFactory,
      MessageConverter jsonMessageConverter) {

    RabbitTemplate rabbitTemplate = new RabbitTemplate(rabbitConnectionFactory);
    rabbitTemplate.setQueue(queueName);
    rabbitTemplate.setExchange(exchangeName);
    rabbitTemplate.setMessageConverter(jsonMessageConverter);

    return rabbitTemplate;
  }


}

如果有任何其他配置/代码有帮助,请告诉我,我也很乐意与您分享。

1 个答案:

答案 0 :(得分:0)

嗯,amqpTemplate.receive()肯定很慢。它基于Channel.basicGet()而不是长寿BasicConsumer。我建议放弃AmqpItemReader赞成来自Spring AMQ MessageListenerContainer的{​​{1}}。