Friday, May 26, 2023

Micro-services pattern. good and bad.


Some patterns get a lot of press, some don’t. Microservices have enjoyed a good run so lets review the good and bad. Like any architecture challenge; using a pattern is really useful in the correct context, but seeing a pattern as a solution for all problems can be really problematic.


the good. 

Microservices can be taken on by a single team, scaled to handle a specific responsibility of the architecture. Services like Auth (auth and accounts), Notifications, Webhooks or other event handlers are usually good candidates to exist as a service


the bad. 

When not being pragmatic, the developer will apply a pattern for the sake of it, in the hopes of getting the benefits. This has led to extremely complex application, where the networking and added infrastructure can lead to slow and buggy applications


take-away. 

Be pragmatic; understand the problem you are solving and the pattern for implementing the solution will become apparent.

Focus on the functionality of the architecture and the other system attributes of performance, security, portability and maintainability will let you know when you want to split out a feature into its own service


A little history


The idea of decoupling functionality into distinct services has been around for about 20 years now. Web Services as a pattern started showing up as the networking and standardization of the protocols started to mature. 


Early networking was done with unique and proprietary protocols, like IIOP and CORBA. Once XML became an standard and the speeds of the infrastructure caught up, the basic setup of XML / HTTP became the common standard. This has now evolved into the JSON / HTTP we use mostly today. 


Smaller web services


Netflix was growing so fast that grouping teams to the functionality and making the deliverables from the teams into distinct services showed a lot promise. It seemed like a team of 5 could handle the functionality for a major software feature, and these big features can be deployed independently and they would communicate to form the product


From this success, the term ‘micro-services’ became a buzzword, and engineering departments felt the need to keep up and adopt this pattern.


Scaling a specific feature


You can always put your monolith app into a kubernetes setup and scale it up. For any service that in the API pattern, where its a stateless processor of requests; this should work fine. 

The trouble can start with other services that have more state and are used differently.


There has been some clear benefits to isolating specific features in the architecture.


Auth (auth and accounts) 

  • this is a high traffic service that needs high quality. using a microservice to handle all the details around identity and permissions, and be able to see this scale. I have seen an auth service running in kubernetes for a very large e-commerce site. On the black friday shopping event, this had over 4200 nodes running!


Notifications 

  • Sending out notifications, and dealing with the dependencies to do that work requires a lot of configuration and specific behanvior.


Webhook or other event handlers. 

  • This type of service is handling a lot of incoming requests and need to have specific configuration and infra.



Too many services


When applying micro-services to any problem, there can be a real problem with the associated complexity. This is sort of the same affect of having many small required libraries in any framework. The whole thing starts to bloat and in the end you could end up wth a monolith of services.


Also, the dependencies between services and the teams developing them will produce a lot of overhead. This can really slow the velocity of an product cycle.


Performance of service based architecture can be improved on the networking side with protobuf and other lower level protocols, but the state management is always going to be a complex problem. How big of a challenge do you need this to be?



Let the problem determine an effective solution. 


Patterns emerge from the architecture, applying patterns for the sake of it just adds needless complexity. Focus on functionality that brings value to your product and as you break down the dependencies and understand your architecture the need to split a specific piece of that functionality into a container will become obvious. 



No comments:

Post a Comment