我正在实现一个服务,该服务需要以可靠和阻塞的方式将消息发布到rabbitmq代理。如中所述https://www.rabbitmq.com/tutorials/tutorial-seven-java.html,有多个用于确认发布者的选项。最基本的选择是使用 waitForConfirms
. 我测试了以下代码(使用设置 cachingConnectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.SIMPLE)
)发布10000条信息花了大约100秒:
rabbitTemplate.invoke(rabbitOperations -> {
rabbitOperations.convertAndSend("test_exchange", "test_key", "test message");
return rabbitOperations.waitForConfirms(1000);
});
我还测试了异步选项(设置为 cachingConnectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED)
)用一个非常原始的阻塞 Package 器。以下代码花费了大约20秒来发布10000条消息:
CountDownLatch latch = new CountDownLatch(1);
CorrelationData correlationData = new CorrelationData();
rabbitTemplate.convertAndSend("test_exchange", "test_key", "test message", correlationData);
correlationData.getFuture().addCallback(success -> {
latch.countDown();
}, failure -> {
latch.countDown();
});
latch.await();
就我所理解的上面链接中的以下引用而言,我的第一个示例应该与我的第二个示例基本相同。
把waitforconfirmsodie看作一个同步的助手,它依赖于后台的异步通知。
但性能差异太大,我的假设不成立。我看到了 RabbitTemplate.invoke
执行的东西比我的第二个代码示例多得多。但这种巨大的性能差异究竟是什么原因呢?我的第二个例子是不好的做法,还是我的第一个例子在某些不必要的方面效率低下?
编辑复制粘贴gary的代码,我经历了以下几点:
StopWatch '': running time = 106379462700 ns
---------------------------------------------
ns % Task name
---------------------------------------------
17546479900 016 % correlated
88832982800 084 % simple
我使用的是windows10pro,rabbitmq3.8.9,通过 docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management
,和Spring Boot2.3.1
编辑2添加 RabbitUtils.isPhysicalCloseRequired()
加里的简单确认码:
simpleTemplate.invoke(ops -> {
ops.convertAndSend("so64857773", "test message");
RabbitUtils.isPhysicalCloseRequired();
return ops.waitForConfirms(1000);
});
产生以下结果:
StopWatch '': running time = 46090067400 ns
---------------------------------------------
ns % Task name
---------------------------------------------
21100935900 046 % correlated
24989131500 054 % simple
似乎在windows上运行rabbitmq的停靠版本时,关闭和重新创建一个通道是相当昂贵的。
edit3使用原生windows10rabbitmq服务器(3.8.9)和erlang23.1.3,性能大大提高。使用10k消息,相关确认测试只花了大约3秒钟。我将下面两个测试的消息数增加到50k。
第一个测试,使用gary的原始代码:
StopWatch '': running time = 144403128200 ns
---------------------------------------------
ns % Task name
---------------------------------------------
19750222900 014 % correlated
124652905300 086 % simple
第二次试验 RabbitUtils.isPhysicalCloseRequired()
如编辑2中所述添加:
StopWatch '': running time = 30030523500 ns
---------------------------------------------
ns % Task name
---------------------------------------------
14549132300 048 % correlated
15481391200 052 % simple
关闭和重新打开一个频道似乎是非常昂贵的windows-这似乎不是一个问题,使用停靠版本。
1条答案
按热度按时间e1xvtsh31#
有更多的代码涉及到相关的确认,所以我本以为该版本需要更多的时间(虽然没有很大的区别)。
我不知道你为什么看到你观察到的行为。
但是,在这两种情况下,最好在等待确认之前发送多个请求;发送和等待每一个都会慢得多。
使用关联确认,您可以保存
CorrelationData
示例,然后等待未来。编辑
我看不到和你一样的行为;我使用这两种方法得到几乎相同的性能;每次大约62秒。
结果: