A while ago you made the decision to move towards an Event-Driven architecture. Then you chose MuleSoft Anypoint Platform to build, deploy and manage your microservices/APIs and Solace PubSub+ Event Broker to handle the communication between them through events.
Well done, you’ve made some great choices.
But as your integration needs grow, so does the usage. And unless you improve your configuration, performance will inevitably start to drop off. You need to allow for higher throughput and consume only the necessary resources and nothing more. Or maybe you’re close to hitting some of the limits on your current subscriptions? Whatever your reasons are, tuning your configurations for increased performance is a must.
While it may seem like a pain, the time you put into tuning up your Solace configuration will pay off.
What do you need or want to achieve?
It’s important to define your goals before you start. Here’s what we suggest you aim for:
- Goal 1: Optimise the resource usage on the Solace PubSub+ broker e.g., the number of client connections used.
- Goal 2: Increase the overall performance on the MuleSoft side e.g., reduce the time taken to establish the connections to Solace PubSub+ broker.
- Goal 3 (the most important): Optimise subscribers and consumers.
So, where do you start?
First, let’s take a look under the hood. Here’s a step-by-step walkthrough of the changes required, starting with a pre-built demo application. The application has two subscribers on two different queues, with each queue attracting events from different topics:
In a nutshell, we have the following:
In Solace, we have the following queues configured:
- adaptiv-erp-order-create-v1 – non-exclusive queue subscribing to “adaptiv/erp/order/create/v1/*” wildcarded topics
- adaptiv-erp-order-update-v1 – non-exclusive queue subscribing to “adaptiv/erp/order/update/v1/*” wildcarded topics
In MuleSoft, we have an application called “ERP Demo Application” that has two JMS Subscribers (aka listeners), one for each of the above queues.
Note: The publishers above are just to complete the picture, but we aren’t focusing on them as part of this tuning exercise.
How to start tuning Solace for MuleSoft
At first glance, it may not seem as though there’s too much you can achieve. If you’re using the OOB (out-of-the-box) JMS connector from MuleSoft which is configured to use the JMS JNDI Connection Factory defined in Solace, you are using the Solace JMS drivers. And of course, you are using the OOB JMS Module from MuleSoft.
Therefore, your configuration probably looks similar to the below:
- You are using the default JMS JNDI Connection Factory in Solace:
- You have configured your JMS Connector to use this JNDI Connection Factory using the Solace JNDI Context Factory, and it may look like this:
- Your JMS Listeners also use more or less default settings.
- When the application is running, you will likely see something like this:
Note the two client connections, one connection for each queue subscriber.
But you don’t have to take my word for it, just look below:
In the queue list, you’ll see we can see both have one subscriber:
So, what’s in there to tweak and tune?
Well, we know you can get more power out of your platforms, and we’re determined to prove it! In the end, even a Ferrari hides some extra ponies just waiting to be unleashed (with the proper know-how of course).
It’s time to get your hands dirty
First things first. It’s probably time for a cleanup.
If you’re still using JMS Topics and Queues, maybe now is the time to get rid of them. Why? Well, they tighten your code to rigid pub/sub constructs. For example, requiring point-to-point communications and lots of customisations in Solace to support the JMS protocol specifics, such as Durable Topic Endpoints. So, if you’re in this situation, the hour has come to move on and use a lighter approach to leverage the power and simplicity of Solace.
In a nutshell, these are the steps we’re going to take:
- Ensure you’re using the latest and the greatest versions of all libraries
- Tune the Solace JMS JNDI connection factory
- Tune the default settings in MuleSoft JMS Connector Config
- Tune the MuleSoft JMS Listeners’ settings
- Tune the MuleSoft JMS publish settings
We didn’t say it was going to be a five-minute job!
So grab a coffee, and let’s do this!
Upgrade the Solace libraries to the latest version:
At the time of writing, the latest is:
Upgrade the JMS Module to the latest version:
At the time of writing, the latest version is:
Reuse connections from the same client id
By default, the Solace Connection Factory allows for only one connection per client id, meaning that same application will use different connections for multiple subscribers, mainly a 1-to-1 relation. So, one client id (autogenerated) for each subscriber, publisher etc.
Note: From a Solace perspective, the client id will always be unique for different applications, or even for multiple instances of the same application. This is because MuleSoft JMS connector config will always add the IP address of the worker (if deployed in CloudHub), or virtual machine, bare metal server (if on-premises, private/public cloud) where MuleSoft server is running.
This setting will allow subscribers/publishers, within the same MuleSoft application and sharing the same JMS Configuration, to also share the same Solace TCP connection.
This is a two-step configuration:
- Change the Solace JMS JNDI Connection Factory to allow duplicate clients.
- Set the client id to a static value in the JMS Connector Config.
Enable connections caching
This does make sense, since establishing a new connection takes some time. But also, it now works hand-in-hand with the previous setting, to allow duplicate client ids.
Disable the lookup destination
Since you’ve already committed to Solace, get ready to bring out those hidden ponies and super-charge its performance! It’s time to unleash Solace’s topic routing power, and use its brilliant architecture of dynamic and lightweight topics to add some serious horsepower.
And now is the best time to move away from the JMS JNDI topics that makes JMS application architectures so rigid.
Increase concurrency for subscribers
Setting this value to something meaningful, i.e., greater than 1, can help with higher throughput and fault resiliency:
Now, because you’ve read this far, here’s a bonus! Below is a sample YAML configuration for the above subscriber’s configuration:
But hold your horses (or ponies)
Let’s first understand what this means from a Solace perspective. If the listener is configured to listen on queue destinations, then the way this value is used it really depends on how the queue is setup in Solace:
- If your use case is throughput, and ordering is not important, then make sure you set the queues as “Non-Exclusive”. This will allow the load balancing between multiples consumers.
- If the use case requires ordering, then set the queues to “Exclusive”. This will allow for one subscriber at a time, but should it fail, there are others to pick up the load.
Regardless of the queue setup, one common thing achieved through this setting is a higher fault tolerance.
Note: Refer to https://docs.solace.com/PubSub-ConceptMaps/Event-Stream-Maps.htm#exclusive-nonexclusive-durable-queues for more details about the difference between exclusive vs non-exclusive queues.
So, after all this, you will see the following changes in your Solace Management Console:
One connection, multiple consumers, instead of one connection per subscriber or publisher:
… and just in case you want proof:
With the queues defined as non-exclusive, we enable higher throughput, so we have some happy load-balanced consumers:
As for the queues, we can also see the same consumers we previously saw in the Client Connections screen:
Happy tuning! May all your integrations perform like Ferraris!