Java Spring AMQP AcknowledgeMode.AUTO运行缓慢
我有一个每秒向RabbitMQ发送20条消息的生产者,还有一个消费者,它应该以与生成消息相同的速度接收消息 我必须实施一些条件:Java Spring AMQP AcknowledgeMode.AUTO运行缓慢,java,spring,amqp,spring-amqp,Java,Spring,Amqp,Spring Amqp,我有一个每秒向RabbitMQ发送20条消息的生产者,还有一个消费者,它应该以与生成消息相同的速度接收消息 我必须实施一些条件: 每秒生成和使用20条消息 保存生产订单 消息不应该丢失(这就是我使用AcknowledgeMode.AUTO的原因) 当我使用SpringAMQP实现(org.springframework.AMQP.rabbit)时,我的消费者每秒最多处理6条消息。但是,如果我使用本机AMQP库(com.rabbitmq.client),它会使用ack-auto和manual每秒处
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(rabbitMqServer);
connectionFactory.setUsername(rabbitMqUsername);
connectionFactory.setPassword(rabbitMqPassword);
return connectionFactory;
}
SpringAMQP(2.0之前)默认预取为1,正如您所说的,即使在拒绝之后也能保证订单
默认情况下,本机客户端不应用任何basicQos()
,这实际上意味着它有无限的预取
所以你不是在比较苹果和苹果
使用本机客户端尝试channel.basicQos(1)
,您将看到与默认spring amqp设置类似的结果
编辑
当比较苹果和苹果时,我得到了类似的结果,有/没有这个框架
@SpringBootApplication
public class So47995535Application {
public static void main(String[] args) {
SpringApplication.run(So47995535Application.class, args).close();
}
private final CountDownLatch latch = new CountDownLatch(100);
private int nativeCount;
private int rlCount;
@Bean
public ApplicationRunner runner(ConnectionFactory factory, RabbitTemplate template,
SimpleMessageListenerContainer container) {
return args -> {
for (int i = 0; i < 100; i++) {
template.convertAndSend("foo", "foo" + i);
}
container.start();
Connection conn = factory.createConnection();
Channel channel = conn.createChannel(false);
channel.basicQos(1);
channel.basicConsume("foo", new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,
byte[] body) throws IOException {
System.out.println("native " + new String(body));
channel.basicAck(envelope.getDeliveryTag(), false);
nativeCount++;
latch.countDown();
}
});
latch.await(60, TimeUnit.SECONDS);
System.out.println("Native: " + this.nativeCount + " LC: " + this.rlCount);
channel.close();
conn.close();
container.stop();
};
}
@Bean
public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.setQueueNames("foo");
container.setPrefetchCount(1);
container.setAutoStartup(false);
container.setMessageListener((MessageListener) m -> {
System.out.println("LC " + new String(m.getBody()));
this.rlCount++;
this.latch.countDown();
});
return container;
}
}
当使用
basicQos(1)
时,无论哪种方法,我都会得到相同的结果-请参阅我的编辑。哦,我明白了。谢谢你的解释。据我所知,不可能满足我的三个条件-速度-可靠性顺序,对吗?除非你能加快处理速度,或者你的网络。通过我的测试(除了增加一个int和倒计时一个锁存器外,在侦听器中根本不做任何工作),使用localhost
上的代理,即使预回迁=1,我也可以达到>4000条消息/秒。因此,我建议您查看侦听器代码的效率。
@Override
public void onMessage(Message message) {saveToDb}
@SpringBootApplication
public class So47995535Application {
public static void main(String[] args) {
SpringApplication.run(So47995535Application.class, args).close();
}
private final CountDownLatch latch = new CountDownLatch(100);
private int nativeCount;
private int rlCount;
@Bean
public ApplicationRunner runner(ConnectionFactory factory, RabbitTemplate template,
SimpleMessageListenerContainer container) {
return args -> {
for (int i = 0; i < 100; i++) {
template.convertAndSend("foo", "foo" + i);
}
container.start();
Connection conn = factory.createConnection();
Channel channel = conn.createChannel(false);
channel.basicQos(1);
channel.basicConsume("foo", new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,
byte[] body) throws IOException {
System.out.println("native " + new String(body));
channel.basicAck(envelope.getDeliveryTag(), false);
nativeCount++;
latch.countDown();
}
});
latch.await(60, TimeUnit.SECONDS);
System.out.println("Native: " + this.nativeCount + " LC: " + this.rlCount);
channel.close();
conn.close();
container.stop();
};
}
@Bean
public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.setQueueNames("foo");
container.setPrefetchCount(1);
container.setAutoStartup(false);
container.setMessageListener((MessageListener) m -> {
System.out.println("LC " + new String(m.getBody()));
this.rlCount++;
this.latch.countDown();
});
return container;
}
}
Native: 50 LC: 50