多线程环境中 RabbitMQ 的性能问题
Performance concrens with RabbitMQ in multi-threaded environemnt
我有两个简单的测试用例。在第一个中,我重用了连接和通道。在第二个中,我只重用连接。有第二个的原因只是为了模拟多线程环境中每个线程场景的通道(这不完全相同,但我们可以了解性能)
所以从第一个我可以发布 70000 msg/sec 而从第二个我只能发布 1500 msg/sec。
- 这是否意味着在 RabbitMQ 中创建通道的成本很高?
- 我们可以使用通道池来解决这个问题吗?
第一个样本
public class Send {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare("myExchange", "direct", true);
channel.queueDeclare("myQueue", true, false, false, null);
for (int i = 0; i < 1000000; i++) {
String message = "{\"id\" : \"56664f85-62e0-11e5-a74b-59530fbb6d8d\"" + i + "}";
channel.basicPublish("", "myQueue", null, message.getBytes("UTF-8"));
}
channel.close();
connection.close(); }
第二个样本
public class Send {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
for (int i = 0; i < 1000000; i++) {
Channel channel = connection.createChannel();
channel.exchangeDeclare("myExchange", "direct", true);
channel.queueDeclare("myQueue", true, false, false, null);
String message = "{\"id\" : \"56664f85-62e0-11e5-a74b-59530fbb6d8d\"" + i + "}";
channel.basicPublish("", "myQueue", null, message.getBytes("UTF-8"));
channel.close();
}
connection.close();
}
我做了一个简单的测试:
final int perfFor = 100000;
d1 = new Date();
for (int i = 0; i < perfFor; i++) {
Channel channel1 = connection.createChannel();
channel1.close();
}
d2 = new Date();
seconds = (d2.getTime() - d1.getTime()) / 1000;
System.out.println("Seconds-Only-CreateDestroyChannels: " + seconds);
final AtomicInteger atomicInteger = new AtomicInteger();
ExecutorService threadChannels = Executors.newFixedThreadPool(1000);
final Date dThread = new Date();
for (int i = 0; i < perfFor; i++) {
threadChannels.submit(new Runnable() {
public void run() {
Channel channel1 = null;
try {
channel1 = connection.createChannel();
channel1.close();
if (atomicInteger.addAndGet(1) == perfFor) {
Date d2 = new Date();
long seconds = (d2.getTime() - dThread.getTime()) / 1000;
System.out.println("Seconds-Only-CreateDestroyChannels MultiThreads: " + seconds);
...
我得到了这个结果:
Seconds-Only-CreateDestroyChannels: 84
Seconds-Only-CreateDestroyChannels MultiThreads: 59
因此,我认为您不需要创建 Channels
池。您应该有一个线程通道,这意味着您启动线程并创建 Channel
.
channel.exchangeDeclare
和 channel.queueDeclare
应该只调用一次,而不是每个 publish
。
你也应该考虑增加Connection
的数量,1.000.000单Connection
似乎有点不平衡。
RabbitMQ 有很多提高性能的方法,您应该考虑所有环境,而不仅仅是 Channels
。
希望对您有所帮助
我有两个简单的测试用例。在第一个中,我重用了连接和通道。在第二个中,我只重用连接。有第二个的原因只是为了模拟多线程环境中每个线程场景的通道(这不完全相同,但我们可以了解性能)
所以从第一个我可以发布 70000 msg/sec 而从第二个我只能发布 1500 msg/sec。
- 这是否意味着在 RabbitMQ 中创建通道的成本很高?
- 我们可以使用通道池来解决这个问题吗?
第一个样本
public class Send {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare("myExchange", "direct", true);
channel.queueDeclare("myQueue", true, false, false, null);
for (int i = 0; i < 1000000; i++) {
String message = "{\"id\" : \"56664f85-62e0-11e5-a74b-59530fbb6d8d\"" + i + "}";
channel.basicPublish("", "myQueue", null, message.getBytes("UTF-8"));
}
channel.close();
connection.close(); }
第二个样本
public class Send {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
for (int i = 0; i < 1000000; i++) {
Channel channel = connection.createChannel();
channel.exchangeDeclare("myExchange", "direct", true);
channel.queueDeclare("myQueue", true, false, false, null);
String message = "{\"id\" : \"56664f85-62e0-11e5-a74b-59530fbb6d8d\"" + i + "}";
channel.basicPublish("", "myQueue", null, message.getBytes("UTF-8"));
channel.close();
}
connection.close();
}
我做了一个简单的测试:
final int perfFor = 100000;
d1 = new Date();
for (int i = 0; i < perfFor; i++) {
Channel channel1 = connection.createChannel();
channel1.close();
}
d2 = new Date();
seconds = (d2.getTime() - d1.getTime()) / 1000;
System.out.println("Seconds-Only-CreateDestroyChannels: " + seconds);
final AtomicInteger atomicInteger = new AtomicInteger();
ExecutorService threadChannels = Executors.newFixedThreadPool(1000);
final Date dThread = new Date();
for (int i = 0; i < perfFor; i++) {
threadChannels.submit(new Runnable() {
public void run() {
Channel channel1 = null;
try {
channel1 = connection.createChannel();
channel1.close();
if (atomicInteger.addAndGet(1) == perfFor) {
Date d2 = new Date();
long seconds = (d2.getTime() - dThread.getTime()) / 1000;
System.out.println("Seconds-Only-CreateDestroyChannels MultiThreads: " + seconds);
...
我得到了这个结果:
Seconds-Only-CreateDestroyChannels: 84
Seconds-Only-CreateDestroyChannels MultiThreads: 59
因此,我认为您不需要创建 Channels
池。您应该有一个线程通道,这意味着您启动线程并创建 Channel
.
channel.exchangeDeclare
和 channel.queueDeclare
应该只调用一次,而不是每个 publish
。
你也应该考虑增加Connection
的数量,1.000.000单Connection
似乎有点不平衡。
RabbitMQ 有很多提高性能的方法,您应该考虑所有环境,而不仅仅是 Channels
。
希望对您有所帮助