2015-09-25 36 views
0

我有兩個簡單的測試用例。在第一個我重新使用連接和頻道。在第二個我只重用連接。第二個原因是爲了模擬多線程環境下的每個線程的通道場景(這不完全相同,但我們可以對性能有所瞭解)多線程environemnt中與RabbitMQ的性能混合

因此,從第一個我可以發佈70000信息/秒,從第二秒我只能發佈1500毫秒/秒。

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

第2個採樣

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

爲什麼在世界上你會產卵數百萬線程? – chrylis

+1

我猜想緩慢可能會宣佈隊列和交流。嘗試刪除這些內容並查看您的費率是否提高。你也應該試着通過修改第二個文件來測試你的理論,以便你有三個for循環。一個用於製作頻道和宣佈隊列/交換,第二個用於發佈消息,第三個用於關閉頻道。 – idbehold

回答

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號,1000000單Connection似乎有點不平衡。

我建議閱讀也thisthis

的RabbitMQ有很多的方法來提高性能,您應該考慮所有的環境,而不僅僅是對Channels

希望它有幫助