RabbitMQ在多线程环境中具有高性能

时间:2015-09-25 20:04:23

标签: java performance rabbitmq

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

所以从第一个开始我可以发布70000 msg /秒,从第二个开始我只能发布1500 msg /秒。

  1. 这是否意味着RabbitMQ中的频道创建成本很高?
  2. 我们可以使用渠道池来解决此问题吗?
  3. 第一个样本

    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();
    }
    

1 个答案:

答案 0 :(得分:2)

我做了一个简单的测试:

 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个数,单个Connection的1.000.000似乎有点不平衡。

我建议您阅读thisthis

RabbitMQ有很多方法可以改善性能,你应该考虑所有环境,而不仅仅是Channels

希望有所帮助