Single vs Multi-threaded JMS Producer

I wanted to see how many times the time difference is to use a multi-threaded producer instead of a single thread. I am setting up ActiveMQ on my local machine, calls the producer class that initializes and starts the JMS connection in its constructor. I set the message limit to 3M and it took about 50 seconds to send all messages to ActiveMQ. I only sent one line "hello world" 3M times.

Then I used the same producer object (one connection but multiple sessions) and started it with an ExecutorService with a thread size of eight. In the method, run

I would divide 3M by 8 to ensure that each thread is sending no more than 375,000 messages. In this case, it took about 60 seconds to enter all the messages.

ExecutorService service = Executors.newFixedThreadPool(8);

    for (int i = 0; i < 8; i++) {

        service.execute(producer);
    }

      

Then I created eight producers, each with their own connection, and they ran them with an ExecutorService or figure-of-eight. This time, it took about 68 seconds to push all 3M messages.

for (int i = 0; i < 8; i++) {
        service.execute(new Producer());
    }

      

I'm wondering why one ceiling producer would do a better job here? I ran each scenario about 10 times, but the results remained the same.

+3


source to share


6 answers


From the point of view of a JMS application, you've written your application to be multithreaded; multiple sessions, each with their own JMS producer objects, managed by separate threads. Assuming your application has no arguments about resources like locks, etc., that's fine.

In terms of efficiency, when sending messages depends on how efficiently the JMS provider is implemented, both from the point of view of client and server sides. Are there any blockages or contentions in the JMS implementation? Maybe it is trying to send everything over the same socket - in this case there is an assertion. Or maybe there is still some kind of castle.



Maybe there is a server side blocking on the server side of the queue database structure.

It really does take detailed knowledge of a particular JMS provider to answer your question.

0


source


The Broker connection uses one TCP / IP connection to enter each message over the wire. In most cases, it would be impractical to use multiple threads that write to the producer on the same connection that all calls will become sequential as they go through the JMS layer to the wire protocol layer. In your case, it takes a little longer due to thread scheduling plus lock contention plus the overhead of thread pool management.

Another thing to consider is that depending on your producer and the addressee, the message you send in the message will be sent in sync with the broker and the producer will block waiting for a confirmation from the broker that the message has been saved and won't be lost. This requires a lot of overhead, but is required for guaranteed message delivery. Even if you are using multiple connections, the bandwidth of all of them may be limited by the speed of the disk the broker is running on, since it must first write all persistent messages.



It is very difficult to use StackOverflow to implement and optimize your code, you need to do some research and understand the implications of the JMS broker architecture and the customizability of the broker you are using. If your threads open a new connection for every message it will be a big performance hit, since establishing a new connection is an expensive operation, so I would recommend looking in the JMS connection pool as a way to improve client performance as well.

In your case, you might want to look at asynchronous dispatches or message batches in a transaction to cut down on the time it takes for each send.

+1


source


Multithreading can be slower than streaming for several reasons. One is that a computer's central processing unit is finite and therefore cannot run all threads at the same time, making it slower. The other is that you also have a finite amount of memory making the thread take longer as it takes up more memory.

Think of multithreading this way you have a corridor that can fit 3 at a time optimally. If you have fewer people walking through this corridor at once, it will take longer to reach all people. Also, if you try to put too many people through it at once, the hallway will clog up and it will be difficult for someone to get through.

This is how multithreading can be bad here and also in some other cases.

-------------------------------------- EDIT WHAT HAPPENS: -------- ------------------------------------------ -

In your problem, you said that you would divide 3M by 8 for one single threaded program so that it will send no more than 375,000 messages. But when did you multithreaded all 3M instead of 375000? If this is true, than the reason why multithreading is slower than single streaming is because java cannot execute different threads at the same time, it looks like it is running at the same time due to its speed, but it really switches between the entire stream that you created. And it takes a little time to switch between them. Several nanoseconds, so it will take longer, although each thread in a multithread works the same in one thread, it has to switch between threads, which makes it take so little time, which is up to 8 seconds, which it took to start.

+1


source


I would prefer the overhead of managing multiple sessions, syncing them with access to a single connection, and switching streams.

Why should it run faster with multiple threads on the send side? The line is just one and the maximum number of threads I can see as the potential performance gain is two - when the first one sends data, the second prepares its data and they switch one at a time.

+1


source


My money is Kalanais's concept. Have you tried to monitor the application while it is running? A simple tool like VisualVM will help you find out where time is spent.

0


source


The difference you noticed is very small, but I think a multi-threaded processor is spending more time because there is concurrency for the processor resources between threads. A multi-threaded processor needs to split the processor between threads and this can cost time and additional processing and sometimes gets slower. While a processor with one thread does not need to share a processor without another thread, it can be more efficient. Another aspect has to do with the resources used for each thread. They only use strings in memory, they do not have access to another resource like disk or database files or TCP ports. In this case, I think a single-thread process will be faster than a multi-thread process.

0


source







All Articles