Search code examples
springrabbitmqspring-amqpspring-rabbit

Understanding, replacing, configuring and modifying Spring Rabbit (AMQP) thread pools: A list of questions


I've got a few short questions about RabbitMQ + Spring , and i'd appreciate your help on this matter.

After reading the documentation
here (https://docs.spring.io/spring-amqp/reference/html/#connections)
and here (https://www.rabbitmq.com/api-guide.html)
it seems the api for the Java + Spring client has a class called CachingConnectionFactory.

The facts:

  1. CachingConnectionFactory has two members of intrest: PublisherConnectionFactory and RabbitConnectionFactory

  2. CachingConnectionFactory extends a parent class called AbstractConnectionFactory

  3. CachingConnectionFactory has a member called (ExecutorService channelsExecutor).

  4. AbstractConnectionFactory has a member called (ExecutorService executorService).

  5. AbstractConnectionFactory has a method called setExecutor(ExecutorService executorService), which sets it's own executorService and then invokes the same method on it's PublisherConnectionFactory

  6. RabbitConnectionFactory has 4 (!) different executors: sharedExecutor, shutdownExecutor, heartbeatExecutor, topologyRecoveryExecutor; It also has a member called nioParams, with another 2 executors: nioExecutor and connectionShutdownExecutor. In addition, it has a method called params, accepting another executor called consumerWorkServiceExecutor. That is 7 executors in total (!!)

  7. It seems the RabbitConnectionFactory, and the docs here (https://www.rabbitmq.com/api-guide.html again), suggest you can pass in any custom executor when creating a channel: rabbitConnectionFactory.newConnection(myExecutorService);

The questions:

  1. What is the difference, and the relationship, between CachingConnectionFactory, PublisherConnectionFactory and RabbitConnectionFactory?

  2. Why do we need so many different executor pools? What is the difference between them all?

  3. Do these classes share their thread pools / executors?

  4. When a connection is opened, to which thread pool is it allocated?

  5. When a channel is opened, to which thread pool is it allocated?

  6. Do publish and consume operations use different thread pools?

  7. How do I pass in my own executor implementation or otherwise configure, each of the aformentioned executors?

  8. Would it be a good idea to merge/unify some or all of the executors?

Thanks in advance


Solution

  • I just answered you on the rabbitmq-users Google Group.

    I can address the Spring questions.

    What is the difference, and the relationship, between CachingConnectionFactory, PublisherConnectionFactory and RabbitConnectionFactory?

    CCF is the main factory; by default. its single connection is shared by all components (but it has a cache mode supporting multiple connections). PCF is an optional CCF that can be used for publishing (when RabbitTemplate.usePublisherConnection is true). This is recommended to allow consumers to continue to consume when publishers are blocked.

    The CCF executorService (if present) is passed into RCF.newConnection(). The channelsExecutor is an internal executor that is only used if publisher confirms are enabled; it is used the defer a channel close request until the publisher confirm arrives (or a timeout).

    Why do we need so many different executor pools? What is the difference between them all? Do these classes share their thread pools / executors?

    The CCF executorService (if present) is passed into RCF.newConnection().

    When a connection is opened, to which thread pool is it allocated?

    The CCF executorService (if present) is passed into RCF.newConnection(). Otherwise the amqp-client uses its own executor.

    When a channel is opened, to which thread pool is it allocated? Do publish and consume operations use different thread pools?

    If RabbitTemplate.usePublisherConnection is true and the PCF has a different executor.

    How do I pass in my own executor implementation or otherwise configure, each of the aformentioned executors?

    There are setter methods for the two CCF executors. If you want a different executor in the PCF, use CCF.getPublisherConnectionFactory() and call its setter.

    Would it be a good idea to merge/unify some or all of the executors?