Unless you've been under a rock, you've probably heard of this new buzz-word: "Micro-services". Many SaaS (Software as a Service) providers are gearing their infrastructures, code architecture, and tooling toward this new magical architectural pattern. So, what are micro-services? Why does our company/team need to embrace this new practice?
To understand the solution that Microservices offers, it's necessary to understand the problem. Most companies deal with technical debt in some shape or form, whether it be from old outdated code from an old outdated tech stack or from refactoring an existing code structure. In a lot of instances, that code structure can be traced back to a monolithic structure. When we talk about "monolithic", we're describing a structure where functionality from either a library or an API is jammed into a single project with no separation of concerns in terms of functional responsibility. This creates a 2-fold snowball effect in terms of slowing a team down:
1. Anytime new functionality is added, removed, or modified, the entire system must be taken down and re-deployed. This is severely disruptive to both the clients, and to the developers on the team. The potential also exists to break functionality to other components (potentially components that have no relation to the code that has been modified)
2. The monolithic model, as a whole, lends itself to bottlenecks in development speed as well as overall system stability. Splitting out a monolithic platform into individual microservices allows developers to focus on individual areas of concern/functionality without worrying about disrupting unrelated, disjoint areas. This allows teams to get items tested and completed more quickly without having to worry about breaking other functional areas.
From a stability perspective, microservices promotes a de-centralization of failure points by spreading out critical system functionality over separate logical areas, all working together to provide enterprise-level services.
Microservices has a very open definition in terms of how it is implemented. When deciding to implement microservices three main questions must be addressed:
1. How will the microservices be defined? In other words, "How do I determine the granularity of a microservice"?
- The complexity in setting up or converting to a microservices architecture is grounded in the definition of what becomes a microservice. This is where domain driven development can help aid in determining the functional areas. You can have too many microservices in your domain and your application becomes chatty and difficult to manage and maintain. You can have too few microservices and your application becomes more monolithic. When breaking down a system into microservices, one must look at how the system as a whole works. From there, the system must be broken down into logical, distinct, and functional pieces that are testable and that do not require interdependencies to fully function on their own. For example, in a medical insurance processing application you could have the following micro-services:
a. Logging Microservice
b. Authentication Microservice
c. Membership Processing Microservice
d. Membership Claims Microservice
2. How will these microservices communicate with each other?
- There are a number of different ways that microservices can communicate. They can communicate via http requests through rest services, or gRPC services. You can use a service bus with a subscriber/receiver methodology. Or even using a third-party service like Redis.
3. What technologies should be utilized to facilitate the microservice architecture?
-Given the decoupled nature of the individual services, the opportunity to use different technologies exists for this architecture. However, this ability also comes with its own set of issues and drawbacks. Using different technologies and frameworks can pose maintainability issues and increase technical debt.
