An example of a Microservice
Imagine that your new, shiny web app is to handle a voluminous load – and at the same time maintain state (session) for that voluminous load. For session storage, in a traditional asp.net (or J2ee) web app, you had two options – in-memory (in-proc) and in SQL (out of proc). There was always a third option (State Server), which was a fancier version of in-memory (one that persisted the state if the web app restarted).
Now, there’s another option; Azure Session Storage. Essentially, take all that session data – and dump it on the cloud. Read it back from the cloud storage as needed.
This is the idea behind a microservice – a key piece of functionality that used to traditionally only be available WITHIN your web-app platform (asp.net or j2ee), is now available as a service. This is in slight contrast to SOA based external services such as GeoLocation or Address Verifications etc. (more on this later).
The microservices world extends to artifacts that are beyond application specific functionality – and transgresses into networking, infrastructure, security and almost any other aspect of a production application. For e.g. the load-balancing requirement of our web app, can now be met without using traditional load balancers. Either AWS’s Elastic Load Balancer, Azure’s Load Balancer or Google’s Worldwide AutoScaling and Load Balancing – all provide load balancing as a managed service. The same is true for firewalls, Gateways, Proxies and a host of other ‘traditional’ networking components.
Note – Not all people extend the definition of microservices to include infrastructure as a service, as I have above.
Having defined what a microservice is, this post examines some of the Good, the Bad and the Ugly when it comes to some popular microservices.
Who doesn’t want to outsource some of their biggest pain points?
- Automatic Scaling? Done!
- Automagic Disaster Recovery? Across Geographically Separated Zones? Done!
- Automatic Failover nodes – for both your app tier and your data tier? – Done!
- Reduced time to market ? By reducing the amount of coding required? – Done!
These are all powerful selling points – and are responsible for some of the reality underlying the hype that surrounds this buzzword. However, having looked at ‘The Good’, now it is time to look at ‘The Bad’ and ‘The Ugly’.
Remote calls are more expensive than in-process calls. This makes you essentially refactor your client code (the consumer of the microservice) – so that your API calls are coarser-grained. This is a bit of a code-maintenance nightmare (the whole idea behind Web Services was to group together service calls that were related – for e.g. AccountCreation and AccountClosure could be part of the same AccountServices class. In the microservices world, AccountCreation would essentially be broken up into a dozen smaller calls (BackgroundCheck….CustomerValidation…etc.). And these set of smaller calls will have no relation to the AccountClosure call – which will have it’s own set of break-up issues.
Some developers would call this downright ‘ugly’ instead of just ‘bad’. It is a bit like taking apart a bicycle and redesigning it so that each part has to be operated independently. Want your front tire to move? Well – you have to do this. Want your back tire to move? You have to do something else – which is unrelated to what you did for the front tire!
Performance – which was meant to be enhanced by ‘micro-servicing’ your app component, might actually slow down due to the excessing remote calls needed to make them work. As an example, when I implemented Session Storage as a Service in Azure App Fabric, the session timeouts actually increased! While AppFabric provide remarkably scalable when it worked, when it didn’t work, it was worse than native session management. Due to the way the ASP.NET runtime ‘holds on’ (locks) a sessionful HTTP request, Azure can actually timeout, even if there is a simple time consuming HTTP request. If your web-app has known issues (for e.g. time consuming Web Service calls), these issues would actually get amplified if you tried to go to a Microservices model.
In brief, Microservices will not fix badly written apps, and in some cases will actually amplify the underlying issue. And that’s bad!
And The Ugly
The ugly can be broken up into two categories –
- It will STILL fail (maybe more than you expect)
- Support is also totally out of your hands.
The whole idea of ‘outsourcing’ key functionality to a microservice relies on the belief that this will lower your own: a) Maintenance Headaches b) Costs and c) Scalability, Failover and D.R. concerns. After all, if leading vendors like Amazon, Microsoft and Google cannot be relied upon to provide close to 100 % uptime, fault-tolerance and real-time recovery – who can? These are the biggest players in the technology world – and surely one can sleep peacefully, knowing that the microservices leveraged by your apps are in safe hands.
However, back to a real world example. Let us look at Load Balancing Solutions out there, specifically – AWS’s Elastic Load Balancer. What happens when the load experiences a sudden spike; say your app is hit by a DDOS (Distributed Denial of Service attack)?
Now, if you had a regular load balancer, it would simply be smart enough and shut down (possibly making your app unavailable, but that is okay, since your app is being attacked). An ELB, in contrast, will simply start scaling to absorb the attack. As it scales, so does your AWS invoice! A recent company (Greatfire.org) faced upto $30,000 PER DAY as a result of this autoscaling feature of ELBs. All well and good that the attack got absorbed – but you are stuck with a half a million dollar bill! When all that was needed was that the ELB shut itself down!
The examples don’t end there. One of the most popular cloud services, RDS ( Relational Database Service ) also has it’s share of challenges. One cannot rely on regular file transfer processes to get data into and out of RDS. This, much like the re-factoring required to accommodate microservices, leads to a redesigning of your entire data lifecycle. In addition, a lot of DBA specific tasks (that DBAs are accustomed to executing on their databases) are simply not possible in the RDS world. A DBA cannot even execute the ALTER SYSTEM command – something that can be used to kill a rogue database session! Flushing the shared pool, modifying REDO logs etc. are all DBA tasks that are no longer possible in RDS.
Support – or lack thereof
When my team encountered the session timeouts (in Azure AppFabric), we first contacted Microsoft. While they were responsive and were quick to diagnose the root cause, they also did not have a workaround for us! They said they were working on a fix that would allow long running services to decouple from the Azure lock out – that our app was seeing. However, there was no ETA.
If your Amazon ELB goes down – or your RDS instance goes down – once again, you are at the mercy of Amazon. There is no ETA on when these services will be restored. While these companies are usually very responsive, it does give one the feeling of helplessness to watch your app go down – and simply wait for someone to restore a service.
To me, that belongs in the ‘Ugly’ column.
Microservices certainly are game changers in the traditional SDLC lifecycle. They can shorten development timelines and allow a quicker time to market for most modern apps. In addition, development teams are forced to move beyond their silo specialty (UI, Database, Middle tier etc.) and are encouraged to think in a more ‘cross functional’ capacity (overall performance of app, failover strategy of app, storage of app data…).
However, like all flashy, shiny buzzwords out there, there’s always a ‘but’.
- Microservices make deployment a breeze, BUT – you may have no control when your production app comes back up (in case of a microservice failure)
- Microservices outsource your scalability and failover pain points, BUT – you may actually end up with comparatively sluggish performance – even if you are paying top-tier subscription rates.
- Microservices save you tons of coding , BUT- you may end up with a refactoring nightmare in your codebase.
- Microservices let you outsource your database platform, BUT – your DBAs cannot do basic, routine tasks on there – such as killing rogue sessions, flushing the memory pool etc.
Microservices are here to stay, of that there’s little doubt. However, adopting a microservices-centric application design has to be weighed with some of the drawbacks that are part-and-parcel of the offering.