多线程环境中 RabbitMQ 的性能问题

Performance concrens with RabbitMQ in multi-threaded environemnt

我有两个简单的测试用例。在第一个中,我重用了连接和通道。在第二个中,我只重用连接。有第二个的原因只是为了模拟多线程环境中每个线程场景的通道(这不完全相同,但我们可以了解性能)

所以从第一个我可以发布 70000 msg/sec 而从第二个我只能发布 1500 msg/sec。

  1. 这是否意味着在 RabbitMQ 中创建通道的成本很高?
  2. 我们可以使用通道池来解决这个问题吗?

第一个样本

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.exchangeDeclarechannel.queueDeclare 应该只调用一次,而不是每个 publish

你也应该考虑增加Connection的数量,1.000.000单Connection似乎有点不平衡。

我建议也阅读 this and this

RabbitMQ 有很多提高性能的方法,您应该考虑所有环境,而不仅仅是 Channels

希望对您有所帮助