In this post we will talk about a performance problem that occurred
in an application that is using Service Bus On-premises. But the problem and
solution is applicable also for any other system that is using not only Service
Bus On-premises but also Azure Service Bus.
Context
We have an application that process a specific type of
messages that are coming through Service Bus. Our application has a dedicated
Topic that is used only by them. A Subscription from another Topic forward
automatically the messages to our application topic.
The current requirement requires that we need to write in
logs all the messages that we are reading from our Application Subscription,
even the one that we don’t need to process. The system that push messages to
our Topic, is pushing a lot of messages to our topic, even messages that we don’t
need to process, but because we need to log all messages that we receive we add
a filter to our Subscription to receive and consume only the messages that we
care.
The application cannot scale by adding more instances. Only
one instance of our app can run, we can only scale up by adding more horse
power (CPU, Memory).
Problem
Because of this we can end up with millions of messages,
where only 2-3% of them are messages that need to be process. A Topic can reach
a limited size and because of the noise that the other system sends to us we
end up with millions of messages that stays in the queue.
The application was design in such a way that cannot scale.
When the load is medium, we reach easily 3-4M messages in the subscription (it seems that when we reach 4M messages, we start to have stability problem).
What we can do consume all this messages, but reducing the
load on our application with minimal costs?
Of course we could say that we should change the system that
push messages to not push messages that we don’t need, but this is not
possible. Another solution is to add a filter on our subscription to ignore
messages that we don’t care, but this is not possible also because we need to
log all messages that were send to our Subscription (Topic).
Solution
A simple solution that I see, that would be compliant will
the given context is to create on our topic one more subscription. On our
initial subscription we would add a filter that would accept only the messages
that we need to process, and a second subscription that accepts messages that
we don’t care, but we need to log.
We can listen to our the second subscription with another application
or with even a listener that is running in the same process like our main application
and the only thing that he does is to log the message in our logger.
In this way, even if we cannot scale our application, by
adding more resources, we can eliminate
from our Topic as soon as possible the messages that we don’t care (having control
on the size of the Topic/Subscription) - having control on the Topic size.
Comments
Post a Comment