Thanks for the response. My response is inline below:<br><br>On Monday, March 26, 2012 7:11:13 AM UTC-7, Steve Powell wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi Josh,<p>In the absence of the experts -- you get me :-)</p><p>Questions that start 'what is the best way to...' often have no<br>definitive answer, I'm afraid; but here goes.</p><p>First, I'm going to have to explain what I *think* you are asking about,<br>before trying to answer it.</p><p>&nbsp; I assume you are asking about multiple Consumers, in a Java client, all<br>&nbsp; consuming from the same queue, allowing 'parallel' consumption -- which<br>&nbsp; I take to mean multi-threaded -- within the same Java client. You want<br>&nbsp; the 'best' application structure which achieves 'parallel' processing of <br>&nbsp; messages from the queue.</p></blockquote><div>Yes - I have one client that is consuming from a single queue, and basically want to achieve the best throughput possible, whatever that means in terms of one or more connections, channels, consumers, and threads making use of these. This is the part I'm not sure about.</div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p>Well, there is nothing to stop you 'registering' the same Consumer<br>instance more than once, with different consumer tags, so it is easy to<br>drive multiple 'identical' Consumers. However, if you register<br>(Channel.basicConsume()) on the same channel, the consumers will be<br>called serially (this is done to preserve the ordering of messages<br>processed on a channel).</p><p>No doubt you've read the blurb on the Java Client API doc pages<br>(<a href="http://www.rabbitmq.com/api-guide.html#consuming" target="_blank">http://www.rabbitmq.com/api-<wbr>guide.html#consuming</a>) which says:</p><p>&gt; Callbacks to Consumers are dispatched on a thread separate from the<br>&gt; thread managed by the Connection. This means that Consumers can safely<br>&gt; call blocking methods on the Connection or Channel, such asqueueDeclare,<br>&gt; txCommit, basicCancel or basicPublish.<br>&gt; <br>&gt; Each Channel has its own dispatch thread. For the most common use case<br>&gt; of one Consumer per Channel, this means Consumers do not hold up other<br>&gt; Consumers. If you have multiple Consumers per Channel be aware that a<br>&gt; long-running Consumer may hold up dispatch of callbacks to other<br>&gt; Consumers on that Channel.</p><p>and the section on advanced connection options mentions a thread-pool<br>(by default containing 5 threads) associated with the connection.</p><p>What this all means is that *on each channel* Consumer callbacks are<br>called serially. No overlapping there, so no chance to consume 'in<br>parallel', so distinct *channels* (on the same connection) are allowed<br>to run their consumers in parallel (up to five may run concurrently, in<br>the default case).</p><p>So, to 'consume' messages in parallel from a single queue you need to<br>have the consumers on separate channels. Now, if you define a single<br>Consumer instance, and get it to be invoked on multiple threads<br>concurrently (on separate channels) you have to be careful -- the code<br>in your Consumer must be thread-safe, and probably more than just that,<br>too. I'll assume you know what you are doing. </p></blockquote><div>&nbsp;</div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p>If you create one Consumer<br>instance for each channel, RabbitMQ will guarantee that each channel's<br>Consumer is running on one thread, so the rules are simpler.</p><p>There is another option. Provided you are prepared to separate<br>consumption from processing (and possibly acknowledgement) you can<br>register a single consumer which does very little except pass the<br>message to another (worker) thread to do the actual processing.</p></blockquote><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p>The<br>Consumer doesn't have to be sophisticated, but your dispatching<br>mechanism needs to be: you mustn't lose messages, and you must ensure<br>that you acknowledge them at some point (which may not be straight<br>away). Still, if you are adept at Java concurrent programming these are<br>all achievable. </p></blockquote><div>This is the approach I've taken so far. I have a single Connection, Channel and Consumer and a single thread that loop on consumer.nextDelivery(). As soon as consumer.nextDelivery() returns, the message is acknowledged and handed off to a separate thread pool for processing, allowing the thread to move on to the next delivery.&nbsp;</div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p>By managing your own worker threads you can achieve your<br>own dispatching and resource management rules, and by setting the<br>pre-fetch count (Qos) and managing acknowledgements you can gate the<br>amount of work done in parallel, and even decide which workers get which<br>messages.</p><p>Which of these is 'best' depends a lot on your requirements. If you need<br>just a little more control over the processing threads but don't want to<br>'roll-your-own' dispatcher mechanism there is an option for you to<br>supply your own ExecutorService for the RabbitMQ Connection to use, and<br>Java supplies some standard ExecutorService implementations which allow<br>you to do some of the management without considerable effort.</p></blockquote><div><br></div><div>My requirements are simply to maximize throughput of my message consumption. Rolling my own dispatcher is probably a bit much.&nbsp;Any alternative configuration recommendations (to the single Connection, Channel, Consumer setup), for maximizing throughput would be appreciated.</div><div><br></div><div>Thanks,</div><div>Josh</div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p>My general advice is that this might be a lot of work, and you should<br>consider investing in a sophisticated system only if you have determined<br>that you really need the advantages it might bring. Be aware that these<br>may not include faster throughput, and might upset any ordering<br>guarantees you may be relying upon at present.</p><p>I hope this helps.</p><p>Steve Powell &nbsp;(a happy kitten)<br>----------some more definitions from the SPD----------<br>chinchilla (n.) Cooling device for the lower jaw.<br>socialcast (n.) Someone to whom everyone is speaking but nobody likes.<br>literacy (n.) A textually transmitted disease usually contracted in childhood.</p><p>On 22 Mar 2012, at 18:20, Josh Stone wrote:</p><p>&gt; I wanted to ask the experts since it's not clear to me - what is the best way to parallelize message consumption from a single queue, using the Java client? <br>&gt; <br>&gt; Thanks,<br>&gt; Josh<br>&gt; ______________________________<wbr>_________________<br>&gt; rabbitmq-discuss mailing list<br>&gt; <a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br>&gt; <a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a></p><p>______________________________<wbr>_________________<br>rabbitmq-discuss mailing list<br><a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br><a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a><br></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p></blockquote><br>On Monday, March 26, 2012 7:11:13 AM UTC-7, Steve Powell wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi Josh,<p>In the absence of the experts -- you get me :-)</p><p>Questions that start 'what is the best way to...' often have no<br>definitive answer, I'm afraid; but here goes.</p><p>First, I'm going to have to explain what I *think* you are asking about,<br>before trying to answer it.</p><p>&nbsp; I assume you are asking about multiple Consumers, in a Java client, all<br>&nbsp; consuming from the same queue, allowing 'parallel' consumption -- which<br>&nbsp; I take to mean multi-threaded -- within the same Java client. You want<br>&nbsp; the 'best' application structure which achieves 'parallel' processing of <br>&nbsp; messages from the queue.</p><p>Well, there is nothing to stop you 'registering' the same Consumer<br>instance more than once, with different consumer tags, so it is easy to<br>drive multiple 'identical' Consumers. However, if you register<br>(Channel.basicConsume()) on the same channel, the consumers will be<br>called serially (this is done to preserve the ordering of messages<br>processed on a channel).</p><p>No doubt you've read the blurb on the Java Client API doc pages<br>(<a href="http://www.rabbitmq.com/api-guide.html#consuming" target="_blank">http://www.rabbitmq.com/api-<wbr>guide.html#consuming</a>) which says:</p><p>&gt; Callbacks to Consumers are dispatched on a thread separate from the<br>&gt; thread managed by the Connection. This means that Consumers can safely<br>&gt; call blocking methods on the Connection or Channel, such asqueueDeclare,<br>&gt; txCommit, basicCancel or basicPublish.<br>&gt; <br>&gt; Each Channel has its own dispatch thread. For the most common use case<br>&gt; of one Consumer per Channel, this means Consumers do not hold up other<br>&gt; Consumers. If you have multiple Consumers per Channel be aware that a<br>&gt; long-running Consumer may hold up dispatch of callbacks to other<br>&gt; Consumers on that Channel.</p><p>and the section on advanced connection options mentions a thread-pool<br>(by default containing 5 threads) associated with the connection.</p><p>What this all means is that *on each channel* Consumer callbacks are<br>called serially. No overlapping there, so no chance to consume 'in<br>parallel', so distinct *channels* (on the same connection) are allowed<br>to run their consumers in parallel (up to five may run concurrently, in<br>the default case).</p><p>So, to 'consume' messages in parallel from a single queue you need to<br>have the consumers on separate channels. Now, if you define a single<br>Consumer instance, and get it to be invoked on multiple threads<br>concurrently (on separate channels) you have to be careful -- the code<br>in your Consumer must be thread-safe, and probably more than just that,<br>too. I'll assume you know what you are doing. If you create one Consumer<br>instance for each channel, RabbitMQ will guarantee that each channel's<br>Consumer is running on one thread, so the rules are simpler.</p><p>There is another option. Provided you are prepared to separate<br>consumption from processing (and possibly acknowledgement) you can<br>register a single consumer which does very little except pass the<br>message to another (worker) thread to do the actual processing. The<br>Consumer doesn't have to be sophisticated, but your dispatching<br>mechanism needs to be: you mustn't lose messages, and you must ensure<br>that you acknowledge them at some point (which may not be straight<br>away). Still, if you are adept at Java concurrent programming these are<br>all achievable. By managing your own worker threads you can achieve your<br>own dispatching and resource management rules, and by setting the<br>pre-fetch count (Qos) and managing acknowledgements you can gate the<br>amount of work done in parallel, and even decide which workers get which<br>messages.</p><p>Which of these is 'best' depends a lot on your requirements. If you need<br>just a little more control over the processing threads but don't want to<br>'roll-your-own' dispatcher mechanism there is an option for you to<br>supply your own ExecutorService for the RabbitMQ Connection to use, and<br>Java supplies some standard ExecutorService implementations which allow<br>you to do some of the management without considerable effort.</p><p>My general advice is that this might be a lot of work, and you should<br>consider investing in a sophisticated system only if you have determined<br>that you really need the advantages it might bring. Be aware that these<br>may not include faster throughput, and might upset any ordering<br>guarantees you may be relying upon at present.</p><p>I hope this helps.</p><p>Steve Powell &nbsp;(a happy kitten)<br>----------some more definitions from the SPD----------<br>chinchilla (n.) Cooling device for the lower jaw.<br>socialcast (n.) Someone to whom everyone is speaking but nobody likes.<br>literacy (n.) A textually transmitted disease usually contracted in childhood.</p><p>On 22 Mar 2012, at 18:20, Josh Stone wrote:</p><p>&gt; I wanted to ask the experts since it's not clear to me - what is the best way to parallelize message consumption from a single queue, using the Java client? <br>&gt; <br>&gt; Thanks,<br>&gt; Josh<br>&gt; ______________________________<wbr>_________________<br>&gt; rabbitmq-discuss mailing list<br>&gt; <a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br>&gt; <a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a></p><p>______________________________<wbr>_________________<br>rabbitmq-discuss mailing list<br><a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br><a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a><br></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p></blockquote><br>On Monday, March 26, 2012 7:11:13 AM UTC-7, Steve Powell wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi Josh,<p>In the absence of the experts -- you get me :-)</p><p>Questions that start 'what is the best way to...' often have no<br>definitive answer, I'm afraid; but here goes.</p><p>First, I'm going to have to explain what I *think* you are asking about,<br>before trying to answer it.</p><p>&nbsp; I assume you are asking about multiple Consumers, in a Java client, all<br>&nbsp; consuming from the same queue, allowing 'parallel' consumption -- which<br>&nbsp; I take to mean multi-threaded -- within the same Java client. You want<br>&nbsp; the 'best' application structure which achieves 'parallel' processing of <br>&nbsp; messages from the queue.</p><p>Well, there is nothing to stop you 'registering' the same Consumer<br>instance more than once, with different consumer tags, so it is easy to<br>drive multiple 'identical' Consumers. However, if you register<br>(Channel.basicConsume()) on the same channel, the consumers will be<br>called serially (this is done to preserve the ordering of messages<br>processed on a channel).</p><p>No doubt you've read the blurb on the Java Client API doc pages<br>(<a href="http://www.rabbitmq.com/api-guide.html#consuming" target="_blank">http://www.rabbitmq.com/api-<wbr>guide.html#consuming</a>) which says:</p><p>&gt; Callbacks to Consumers are dispatched on a thread separate from the<br>&gt; thread managed by the Connection. This means that Consumers can safely<br>&gt; call blocking methods on the Connection or Channel, such asqueueDeclare,<br>&gt; txCommit, basicCancel or basicPublish.<br>&gt; <br>&gt; Each Channel has its own dispatch thread. For the most common use case<br>&gt; of one Consumer per Channel, this means Consumers do not hold up other<br>&gt; Consumers. If you have multiple Consumers per Channel be aware that a<br>&gt; long-running Consumer may hold up dispatch of callbacks to other<br>&gt; Consumers on that Channel.</p><p>and the section on advanced connection options mentions a thread-pool<br>(by default containing 5 threads) associated with the connection.</p><p>What this all means is that *on each channel* Consumer callbacks are<br>called serially. No overlapping there, so no chance to consume 'in<br>parallel', so distinct *channels* (on the same connection) are allowed<br>to run their consumers in parallel (up to five may run concurrently, in<br>the default case).</p><p>So, to 'consume' messages in parallel from a single queue you need to<br>have the consumers on separate channels. Now, if you define a single<br>Consumer instance, and get it to be invoked on multiple threads<br>concurrently (on separate channels) you have to be careful -- the code<br>in your Consumer must be thread-safe, and probably more than just that,<br>too. I'll assume you know what you are doing. If you create one Consumer<br>instance for each channel, RabbitMQ will guarantee that each channel's<br>Consumer is running on one thread, so the rules are simpler.</p><p>There is another option. Provided you are prepared to separate<br>consumption from processing (and possibly acknowledgement) you can<br>register a single consumer which does very little except pass the<br>message to another (worker) thread to do the actual processing. The<br>Consumer doesn't have to be sophisticated, but your dispatching<br>mechanism needs to be: you mustn't lose messages, and you must ensure<br>that you acknowledge them at some point (which may not be straight<br>away). Still, if you are adept at Java concurrent programming these are<br>all achievable. By managing your own worker threads you can achieve your<br>own dispatching and resource management rules, and by setting the<br>pre-fetch count (Qos) and managing acknowledgements you can gate the<br>amount of work done in parallel, and even decide which workers get which<br>messages.</p><p>Which of these is 'best' depends a lot on your requirements. If you need<br>just a little more control over the processing threads but don't want to<br>'roll-your-own' dispatcher mechanism there is an option for you to<br>supply your own ExecutorService for the RabbitMQ Connection to use, and<br>Java supplies some standard ExecutorService implementations which allow<br>you to do some of the management without considerable effort.</p><p>My general advice is that this might be a lot of work, and you should<br>consider investing in a sophisticated system only if you have determined<br>that you really need the advantages it might bring. Be aware that these<br>may not include faster throughput, and might upset any ordering<br>guarantees you may be relying upon at present.</p><p>I hope this helps.</p><p>Steve Powell &nbsp;(a happy kitten)<br>----------some more definitions from the SPD----------<br>chinchilla (n.) Cooling device for the lower jaw.<br>socialcast (n.) Someone to whom everyone is speaking but nobody likes.<br>literacy (n.) A textually transmitted disease usually contracted in childhood.</p><p>On 22 Mar 2012, at 18:20, Josh Stone wrote:</p><p>&gt; I wanted to ask the experts since it's not clear to me - what is the best way to parallelize message consumption from a single queue, using the Java client? <br>&gt; <br>&gt; Thanks,<br>&gt; Josh<br>&gt; ______________________________<wbr>_________________<br>&gt; rabbitmq-discuss mailing list<br>&gt; <a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br>&gt; <a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a></p><p>______________________________<wbr>_________________<br>rabbitmq-discuss mailing list<br><a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br><a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a><br></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p></blockquote><br>On Monday, March 26, 2012 7:11:13 AM UTC-7, Steve Powell wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi Josh,<p>In the absence of the experts -- you get me :-)</p><p>Questions that start 'what is the best way to...' often have no<br>definitive answer, I'm afraid; but here goes.</p><p>First, I'm going to have to explain what I *think* you are asking about,<br>before trying to answer it.</p><p>&nbsp; I assume you are asking about multiple Consumers, in a Java client, all<br>&nbsp; consuming from the same queue, allowing 'parallel' consumption -- which<br>&nbsp; I take to mean multi-threaded -- within the same Java client. You want<br>&nbsp; the 'best' application structure which achieves 'parallel' processing of <br>&nbsp; messages from the queue.</p><p>Well, there is nothing to stop you 'registering' the same Consumer<br>instance more than once, with different consumer tags, so it is easy to<br>drive multiple 'identical' Consumers. However, if you register<br>(Channel.basicConsume()) on the same channel, the consumers will be<br>called serially (this is done to preserve the ordering of messages<br>processed on a channel).</p><p>No doubt you've read the blurb on the Java Client API doc pages<br>(<a href="http://www.rabbitmq.com/api-guide.html#consuming" target="_blank">http://www.rabbitmq.com/api-<wbr>guide.html#consuming</a>) which says:</p><p>&gt; Callbacks to Consumers are dispatched on a thread separate from the<br>&gt; thread managed by the Connection. This means that Consumers can safely<br>&gt; call blocking methods on the Connection or Channel, such asqueueDeclare,<br>&gt; txCommit, basicCancel or basicPublish.<br>&gt; <br>&gt; Each Channel has its own dispatch thread. For the most common use case<br>&gt; of one Consumer per Channel, this means Consumers do not hold up other<br>&gt; Consumers. If you have multiple Consumers per Channel be aware that a<br>&gt; long-running Consumer may hold up dispatch of callbacks to other<br>&gt; Consumers on that Channel.</p><p>and the section on advanced connection options mentions a thread-pool<br>(by default containing 5 threads) associated with the connection.</p><p>What this all means is that *on each channel* Consumer callbacks are<br>called serially. No overlapping there, so no chance to consume 'in<br>parallel', so distinct *channels* (on the same connection) are allowed<br>to run their consumers in parallel (up to five may run concurrently, in<br>the default case).</p><p>So, to 'consume' messages in parallel from a single queue you need to<br>have the consumers on separate channels. Now, if you define a single<br>Consumer instance, and get it to be invoked on multiple threads<br>concurrently (on separate channels) you have to be careful -- the code<br>in your Consumer must be thread-safe, and probably more than just that,<br>too. I'll assume you know what you are doing. If you create one Consumer<br>instance for each channel, RabbitMQ will guarantee that each channel's<br>Consumer is running on one thread, so the rules are simpler.</p><p>There is another option. Provided you are prepared to separate<br>consumption from processing (and possibly acknowledgement) you can<br>register a single consumer which does very little except pass the<br>message to another (worker) thread to do the actual processing. The<br>Consumer doesn't have to be sophisticated, but your dispatching<br>mechanism needs to be: you mustn't lose messages, and you must ensure<br>that you acknowledge them at some point (which may not be straight<br>away). Still, if you are adept at Java concurrent programming these are<br>all achievable. By managing your own worker threads you can achieve your<br>own dispatching and resource management rules, and by setting the<br>pre-fetch count (Qos) and managing acknowledgements you can gate the<br>amount of work done in parallel, and even decide which workers get which<br>messages.</p><p>Which of these is 'best' depends a lot on your requirements. If you need<br>just a little more control over the processing threads but don't want to<br>'roll-your-own' dispatcher mechanism there is an option for you to<br>supply your own ExecutorService for the RabbitMQ Connection to use, and<br>Java supplies some standard ExecutorService implementations which allow<br>you to do some of the management without considerable effort.</p><p>My general advice is that this might be a lot of work, and you should<br>consider investing in a sophisticated system only if you have determined<br>that you really need the advantages it might bring. Be aware that these<br>may not include faster throughput, and might upset any ordering<br>guarantees you may be relying upon at present.</p><p>I hope this helps.</p><p>Steve Powell &nbsp;(a happy kitten)<br>----------some more definitions from the SPD----------<br>chinchilla (n.) Cooling device for the lower jaw.<br>socialcast (n.) Someone to whom everyone is speaking but nobody likes.<br>literacy (n.) A textually transmitted disease usually contracted in childhood.</p><p>On 22 Mar 2012, at 18:20, Josh Stone wrote:</p><p>&gt; I wanted to ask the experts since it's not clear to me - what is the best way to parallelize message consumption from a single queue, using the Java client? <br>&gt; <br>&gt; Thanks,<br>&gt; Josh<br>&gt; ______________________________<wbr>_________________<br>&gt; rabbitmq-discuss mailing list<br>&gt; <a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br>&gt; <a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a></p><p>______________________________<wbr>_________________<br>rabbitmq-discuss mailing list<br><a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br><a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a><br></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p></blockquote><br>On Monday, March 26, 2012 7:11:13 AM UTC-7, Steve Powell wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi Josh,<p>In the absence of the experts -- you get me :-)</p><p>Questions that start 'what is the best way to...' often have no<br>definitive answer, I'm afraid; but here goes.</p><p>First, I'm going to have to explain what I *think* you are asking about,<br>before trying to answer it.</p><p>&nbsp; I assume you are asking about multiple Consumers, in a Java client, all<br>&nbsp; consuming from the same queue, allowing 'parallel' consumption -- which<br>&nbsp; I take to mean multi-threaded -- within the same Java client. You want<br>&nbsp; the 'best' application structure which achieves 'parallel' processing of <br>&nbsp; messages from the queue.</p><p>Well, there is nothing to stop you 'registering' the same Consumer<br>instance more than once, with different consumer tags, so it is easy to<br>drive multiple 'identical' Consumers. However, if you register<br>(Channel.basicConsume()) on the same channel, the consumers will be<br>called serially (this is done to preserve the ordering of messages<br>processed on a channel).</p><p>No doubt you've read the blurb on the Java Client API doc pages<br>(<a href="http://www.rabbitmq.com/api-guide.html#consuming" target="_blank">http://www.rabbitmq.com/api-<wbr>guide.html#consuming</a>) which says:</p><p>&gt; Callbacks to Consumers are dispatched on a thread separate from the<br>&gt; thread managed by the Connection. This means that Consumers can safely<br>&gt; call blocking methods on the Connection or Channel, such asqueueDeclare,<br>&gt; txCommit, basicCancel or basicPublish.<br>&gt; <br>&gt; Each Channel has its own dispatch thread. For the most common use case<br>&gt; of one Consumer per Channel, this means Consumers do not hold up other<br>&gt; Consumers. If you have multiple Consumers per Channel be aware that a<br>&gt; long-running Consumer may hold up dispatch of callbacks to other<br>&gt; Consumers on that Channel.</p><p>and the section on advanced connection options mentions a thread-pool<br>(by default containing 5 threads) associated with the connection.</p><p>What this all means is that *on each channel* Consumer callbacks are<br>called serially. No overlapping there, so no chance to consume 'in<br>parallel', so distinct *channels* (on the same connection) are allowed<br>to run their consumers in parallel (up to five may run concurrently, in<br>the default case).</p><p>So, to 'consume' messages in parallel from a single queue you need to<br>have the consumers on separate channels. Now, if you define a single<br>Consumer instance, and get it to be invoked on multiple threads<br>concurrently (on separate channels) you have to be careful -- the code<br>in your Consumer must be thread-safe, and probably more than just that,<br>too. I'll assume you know what you are doing. If you create one Consumer<br>instance for each channel, RabbitMQ will guarantee that each channel's<br>Consumer is running on one thread, so the rules are simpler.</p><p>There is another option. Provided you are prepared to separate<br>consumption from processing (and possibly acknowledgement) you can<br>register a single consumer which does very little except pass the<br>message to another (worker) thread to do the actual processing. The<br>Consumer doesn't have to be sophisticated, but your dispatching<br>mechanism needs to be: you mustn't lose messages, and you must ensure<br>that you acknowledge them at some point (which may not be straight<br>away). Still, if you are adept at Java concurrent programming these are<br>all achievable. By managing your own worker threads you can achieve your<br>own dispatching and resource management rules, and by setting the<br>pre-fetch count (Qos) and managing acknowledgements you can gate the<br>amount of work done in parallel, and even decide which workers get which<br>messages.</p><p>Which of these is 'best' depends a lot on your requirements. If you need<br>just a little more control over the processing threads but don't want to<br>'roll-your-own' dispatcher mechanism there is an option for you to<br>supply your own ExecutorService for the RabbitMQ Connection to use, and<br>Java supplies some standard ExecutorService implementations which allow<br>you to do some of the management without considerable effort.</p><p>My general advice is that this might be a lot of work, and you should<br>consider investing in a sophisticated system only if you have determined<br>that you really need the advantages it might bring. Be aware that these<br>may not include faster throughput, and might upset any ordering<br>guarantees you may be relying upon at present.</p><p>I hope this helps.</p><p>Steve Powell &nbsp;(a happy kitten)<br>----------some more definitions from the SPD----------<br>chinchilla (n.) Cooling device for the lower jaw.<br>socialcast (n.) Someone to whom everyone is speaking but nobody likes.<br>literacy (n.) A textually transmitted disease usually contracted in childhood.</p><p>On 22 Mar 2012, at 18:20, Josh Stone wrote:</p><p>&gt; I wanted to ask the experts since it's not clear to me - what is the best way to parallelize message consumption from a single queue, using the Java client? <br>&gt; <br>&gt; Thanks,<br>&gt; Josh<br>&gt; ______________________________<wbr>_________________<br>&gt; rabbitmq-discuss mailing list<br>&gt; <a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br>&gt; <a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a></p><p>______________________________<wbr>_________________<br>rabbitmq-discuss mailing list<br><a href="mailto:rabbitmq-discuss@lists.rabbitmq.com" target="_blank">rabbitmq-discuss@lists.<wbr>rabbitmq.com</a><br><a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/<wbr>cgi-bin/mailman/listinfo/<wbr>rabbitmq-discuss</a><br></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p></blockquote>