Understanding Concurrency in Mule 3 ESB

Enterprise service Bus (ESB) is an approach for application integration in distributed and heterogeneous environments. One of the requirements for ESB is a highly concurrent system. Mule ESB is a lightweight Java-based Enterprise Service Bus (ESB) and Integration Platform that allows developers to connect applications and enables data exchange.

Mule provides three layers of highly configurable concurrency called `thread pools.’

  1. Receiver Thread Pool – which originally receives the message, and either

-Synchronously processes the entire flow, or
-Asynchronously ends it by writing a message to a queue.

2. Flow Thread Pool – which asynchronously processes the bulk of the flow.
3. Dispatcher Thread Pool – which sends messages asynchronously to one-way endpoints.

Synchronous vs. Asynchronous processing in Mule:

For synchronous processing, the same thread will be used to carry the message through Mule. If the message needs to be sent to an outbound endpoint, the following will apply:

  1. If the outbound endpoint is one-way, the message is sent using the same thread. Once sent, the thread resumes processing the same message. It does not wait for the message to be received by the remote endpoint.
  2. If the outbound endpoint is request-response, the flow thread sends a message to the outbound endpoint and waits for a response. When the response arrives, the flow threads resumes by processing the response.

For asynchronous processing, the receiver thread is used only to place the message on a SEDA queue. At this point, the message is transferred to a flow thread.  The receiver thread is then released into the receiver thread pool so it can carry another message.

When a message is processed, if it needs to be sent to an outbound endpoint, one of the following applies:

  1. If the outbound endpoint is one-way, the message is copied, and the copy processed by a dispatcher thread while the flow thread continues processing the original message in parallel.
  2. If the outbound endpoint is request-response, the flow thread sends a message to the outbound endpoint and waits for a response. When the response arrives, the flow threads resumes by processing the response.

Conceptually, messages are processed by flows in three stages:

  1. The message being received by the inbound connector
  2. The message being processed
  3. The message being sent via an outbound connector.

 

Even if the connector is not provided for inbound or outbound, Mule creates a default connector with default configurations for each endpoint.

Example:

There needs to be a sftp end point (inbound) and two levels of configured concurrency – the Receiver Thread pool and the Flow Thread pool. The Dispatcher Thread pool can be configured in the same way and will give the same performance.

  1. sftp:inbound-endpoint exchange-pattern=”request-response” and receiver-threading-profile doThreading=”false” – Multiple receiver threads get created and performance is very slow due to synchronous nature of flow (request-response exchange pattern)
  2. sftp:inbound-endpoint exchange-pattern=”one-way” and receiver-threading-profile doThreading=”false” – Multiple receiver threads get created, and performance is better than Case 1 but due to multithreading, a race condition could occur causing multiple threads to start consuming the same file. This is especially true when file size is large
  3. sftp:inbound-endpoint exchange-pattern=”one-way” and receiver-threading-profile doThreading=”true” maxThreadsActive=”1″ maxThreadsIdle=”1″ poolExhaustedAction=”DISCARD” – Only one thread gets created and performance is the same as  in Case 2.  However, there is no way to set the threadWaitTimeout in this case and hence once the thread times out after the default value, the system will stop consuming more messages (files in this case)
  4. sftp: inbound-endpoint exchange-pattern=”one-way” and receiver-threading-profile doThreading=”true” maxThreadsActive=”1″ maxThreadsIdle=”1″ poolExhaustedAction=”WAIT” maxBufferSize=”1″ threadWaitTimeout=”-1″ – Only one thread is created and performance is the same as in Cases 2 and 3. We have set the threadWaitTimeout to indefinite as there is only one active thread, and it will keep on pooling forever.

 

Catch:

The catch is that configuring the receiver-threading-profile doThreading=”false” has no impact whatsoever in the overall processing. Internally there will be multiple (default) receiver threads that will be created. So don’t rely on doThreading=”false” alone to stop multithreading. Instead do the same configurations as mentioned in Point 4 above. The same is applicable to dispatcher-threading-profile.

Reference:

http://www.mulesoft.org/documentation/display/current/Tuning+Performance

Tags :

Related insights

  • All Posts
  • Article
  • Awards & Recognition
  • Blog
  • Brochures
  • Case Studies
  • Fintech
  • Insights
  • News
  • Stories
  • Testimonials
  • Uncategorized
  • Whitepaper
  • All Posts
  • Article
  • Awards & Recognition
  • Blog
  • Brochures
  • Case Studies
  • Fintech
  • Insights
  • News
  • Stories
  • Testimonials
  • Uncategorized
  • Whitepaper

Let’s create new possibilities with technology