Reputation: 433
I have two simple test cases. In the first one I'm reusing both connection and channel. In the second one I'm reusing only the connection. Reason for having the second one is just to simulate channel per thread scenario in multi-threaded environment(this is not exactly same, but we can get an idea about the performance)
So from the first one I can publish 70000 msg/sec and from the second I can publish only 1500 msg/sec.
1st Sample
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(); }
2nd Sample
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();
}
Upvotes: 0
Views: 120
Reputation: 22682
I made a simple test:
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);
...
I got this results:
Seconds-Only-CreateDestroyChannels: 84
Seconds-Only-CreateDestroyChannels MultiThreads: 59
So, I don't think you need to create a Channels
pool. You should have a channel for thread, it means you start you thread and create the Channel
.
channel.exchangeDeclare
and channel.queueDeclare
should be called just one time and not for each publish
.
You also should consider to increase the Connection
number, 1.000.000 for single Connection
seems a bit unbalanced.
I suggest to read also this and this
RabbitMQ has lot ways to improve the performance, and you should consider all your environment and not just about the Channels
.
hope it helps
Upvotes: 2