In the early days of my career, monolithic APIs were common. SOAP and XML were still popular - REST and JSON were the new kids on the block.
I worked in a development team that had inherited a monolithic API. A bad deployment left multiple key systems inoperable, and our support lines were inundated to the point that we purchased “apology doughnuts” for the team.
A colleague suggested moving our platform to microservices. This three-part blog series explores how this transformed the business. The second post elaborates on the kind of problems serverless functions solve. The final post will explore longer-term options for hosting Azure Functions using containers and Kubernetes.
My monolithic meltdown
A friend asked me - “Are microservices just a buzzword?”. I responded with a story from my early career:
Our development team had inherited an existing (monolithic) API that powered the checkout for a popular app. The same API powered the monthly billing process. Once a month the billing department smashed the API with requests over a couple of hours.
As the number of requests grew from thousands to millions, the checkout was brought to its knees. Support was inundated with complaints. The billing department was afraid to run their billing process during office hours. Donuts weren’t going to cut it.
We attempted “vertical scaling” by adding RAM to the servers. This worked for a while. But servers had to be restarted – disrupting the checkout. And eventually, we hit the server RAM limits.
The next sprint planning catalysed our adventures into microservices. We split our monolith into multiple (microservice) APIs, grouped by related business functions. These microservices could be maintained, deployed and scaled-out (or “horizontally-scaled”) independently. Demands like memory usage could then be divided among less powerful - far cheaper - server instances behind a load balancer. This minimised service disruption when scaling and deploying since we could add and remove instances from the load-balancer.
But the biggest win was that stress on the billing microservice was better isolated from the checkout microservice. Traffic was handled - sales were made - doughnut budgets were slashed.
High-availability hosting - my “Yay, cloud!” moment
Soon after our adventures in microservices, the marketing team launched a series of successful campaigns. This was great for the business, but it created traffic peaks that pushed the limits of our servers. We either needed to add more servers or find a better solution.
Cloud hosting was the new thing in vogue. We pitched it to our bosses, who argued that the “cloud was someone else’s computer, right?”. So, we responded with the following questions:
- we are developers – who is responsible for maintaining and adding server infrastructure?
- do you want us to work on infrastructure or new features?
- what if the data centre becomes unavailable because of a natural disaster? Will the services stay available? How will we recover?
These problems could have been solved by hiring IT staff and spending several months spinning up this capability. But we were not in the web hosting business, and we had products to build. It was decided - we would outsource the hosting of our services to a cloud provider. Azure was identified as a good fit.
Microsoft provides this responsibility matrix, which shows how responsibility is delegated more and more to the Azure platform for different product offerings:
Moving from right-to-left from IaaS (Infrastructure as a Service) to PaaS (Platform as a Service), note how the cloud provider handles more and more of the hosting concerns. IaaS allows provisioning virtual machines in the cloud for fine-grained control. However, the customer was responsible for maintaining these servers - something we were trying to get away from...
We opted for a PaaS offering for our APIs - so we could focus more on feature development and less on provisioning machines and other infrastructure. Azure App Services was the service we decided on to host our APIs. It provided tooling which allowed us to run a single command to deploy an API and let Azure worry about provisioning servers and running updates. We also decided to use Azure Functions for background tasks. At the time this was Azure’s new FaaS (Functions as a Service), or “serverless” offering. Serverless was another huge win for us, which I’ll cover in the next post.
The IT world is buzzword heavy. But in the case of microservices, I can honestly say they made my work life better. At worst - I hope you found this story mildly entertaining. But my hope is you walk away with a new perspective on the value of microservice architecture, horizontal scaling and how the cloud can help make this a reality.
In the next post, I will explain how Azure Functions and serverless took our hosting adventures to the next peak.