Create A Multi User Experience For Single Threaded Applications Using Azure Container Apps
How to make a single-threaded app multi-threaded? This is the scenario I faced very recently. These were legacy web app(s) written to be single-threaded; in this context single-threaded means can only serve one request at a time. I know this goes against everything that a web app should be, but it what it is.
So if we have a single threaded web app (legacy) now all of a sudden we have a requirement to support multiple users at the same time. What are our options:
- Re-architect the app to be multi threaded
- Find a way to simulate multi threaded behavior
Both are great options, but in this scenario option 1 was out, due to the cost involved in re-writing this app to support multi threading. So that leaves us with option 2; how can we at a cloud infra level easily simulate multi threaded behavior. Turns out if we containerize the app (in this case it was easy enough to do) we orchestrate the app such that for each http request is routed to a new container (ie: every new http request should spin up a new container and request send to it)
Options For Running Containers
So when it comes to running a container in Azure our main options are below
Here we need to orchestrate containers, ie: at a minimum for every new http request spin a new one), which means we only have two viable options, Azure Kubernetes Service (AKS) or Azure Container Apps (ACA). Both are valid options, each with their own pros/cons, with AKS its a lot more complex we will need to :
- Think of networking
- Think of vm’s/vm scale sets for nodes
- Choose ingress controller and set up ingress rules
- Identity
- Plus many more, here is the baseline reference for AKS
So in short, as flexible as AKS is its not as easy as something like ACA which is a fully managed version of AKS that abstracts all the complexities of Kubernetes. So for this scenario to prove we can simulate multi threaded experience lets go ahead with ACA.
Sample Single Threaded Program
For this demo below is a simple C# DotNet app that simulates a single threaded behavior, essentially its doing a lock on a static variable which blocks the whole process for 6 seconds. So when we visit the /test endpoint we lock the whole app.
1 | public class Program |
Azure Container Apps
For this demo the easiest way to create the Azure Container Apps environment is through Visual Studio, you right click, publish and go through the menus and in the end VS will create a Container Apps Environment and deploy the code as a container to ACA.
Once this is all done, we should have a resource group like below
Azure Container Apps Scaling
Next we go to the container app (the single threaded api we just deployed) and set up a simple http scale rule that will spin up a new container for every 1 http incoming request. In the example below we set min-replicas to 0 and max to 30 this means that when there is no traffic it will scale down to 0 and at peak it will hit 30.
Testing
Now go to the url of the container app and hit it simultaneously in browser tabs, when I opened it in multiple browser tabs out of 10 tabs about 7 were served by unique containers and based on the test code above I see it being served by different container ids
1 | Tab1: Hello From Container: single-threaded-api-app-20220731--ps4yjjp-66f4885b65-w5s6h |
So its not 100% every single request goes to a brand new container, but very easily and very quickly with out too much complexity we were able to achieve a 70 - 90% of requests being served with new containers, so in essence we found a quick way to simulate a pseudo - multi threaded experience for our legacy single threaded app with out too much effort.
Create A Multi User Experience For Single Threaded Applications Using Azure Container Apps