Services vs Microservices — what did we build?

Container based applications have been around for a while in large Internet businesses. It is now becoming mainstream in the rest of the world. At CloudMunch, we recently completed this transition for our platform. One question that came up was

Are we Microservices based?

I wanted to say we were, but then thought about it some more and wrote this article.

There has been enough written about this already and my belief is that there is very little symantic difference between them. The goal is to minimize dependencies and manage the overall complexity and meeting the business objective of faster time to market with higher predictability and reliability. Let’s start by examining generally accepted definitions

Here is what Martin Fowler had to say about Microservice

“… the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services …”

Here is what Don Box had to say about Service oriented Architecture

1. Boundaries are explicit
 2. Services are autonomous
 3. Services share schema and contract, not class
 4. Service compatibility is based on policy

Comparison

Let’s first examine the similarities between the two architecture styles. Both of them emphasize the autonomy and explicit boundaries. What this translates into is that there are individual teams working on the services. The real benefit here is decomposing the application into smaller “chunks”, so that the engineering process is more manageable and predictable. And specifically, there is loose coupling between the teams.

This enables release cycles to be distinct and teams to focus on their features and velocity than trying to co-ordinate an uber release. There are probably key releases where the schedules are aligned, but minor releases can happen separately. Being able to deploy in an automated manner is critical in either approach — whether you want to do Blue-green deployment or Canary deployment. Automation allows for the deployments to be validated and rolled back.

The primary difference is the scope of these services and centralization of management. Microservices focus on a specific area of the application, like executing a step in an automation task, writing the output and waiting for the next trigger. The data model used is local to the microservice and events are propagated through API calls or lightweight Pub/Sub mechanisms — for example, aggregating the result across all the steps in the task, creating insights and persisting that to storage.

Here is where the microservices principles differ from service oriented architecture — centralized management through a Enterprise Service and other methods of communication between the services vs simple lightweight communication mechanisms through APIs that are versioned or fully backwards compatible. As Martin Fowler suggests, microservices is in some way SOA done right as well as microservices approach being a subset of SOA.

SOA-microservice

What is the best approach

The best approach is to start with a few services encapsulations that are good for loose coupling and maintainability. Then focus on building automation in the functional areas for each service — commit to quality validation, deployment, resource monitoring and performance. Create independent delivery pipelines and connect all the tools used in the application lifecycle for an end-to-end perspective. I won’t delve into the design principles of microservice as they are language and application specific. Regardless of the stack or architecture, instrumentation is critical.

Roll up analytics for each of these services into a common dashboard that allows for understanding critical metrics across all the services like Code Quality, performance and resource usage. Having an application level context will bring to light areas where there can be further decoupliing resulting in decomposing services up into further microservices. For example, the resource usage profile of a analytics service might indicate that us that we have two different types of acitivities in a service — one is IO bound and another is CPU bound. It makes sense to split them into individual microservices — one for gather the data and another for processing the metrics.

global-dashboard

The post has so far focused on application services. What about database components? The ideal approach is to share nothing, including data between the services. This allows data model and schema changes to be completely local. When migrating from a few services approach, this might be difficult to achieve. Another approach is for the schema to be fully backwards compatible and have a period of time where old and new schema can exist. Then build other microservices that can “clean-up” the data in ensuring there is consistency. This requires the microservices working on the data also to be fully aware of the schema changes. There are many strategies to use and this will be a topic for a future post.

One area that becomees critical is the ability to monitor the services for ensuring availability and behavior. With the container orchestration strategies like Kubernetes, the availability problem is greatly simplified. We still need ways to clearly understand that the microservices are acting the way they are supposed to resulting in a consistent, recoverable and expected state of the flow in the application. Before we start creating more microservices, it is important to have strategies to validate consistency of application state, as well have ways to handle any inconsistencies.

There is no magic number for how many services you need to have to be a microservices oriented architecture. CloudMunch is itself broken into four different services, with the goal to break one of the services down to a large number of smaller services. We are doing this based on execution boundaries, resource & scale requirements balancing with the overall complexity of management.

Summary

You don’t have to be Containerized application to be Services oriented, but not having a Services approach will cause a lot of pain if you want to adopt a Containerized model. Microservices, as the name suggests are simply compact services, that may share nothing and can be updated independently with no impact to uptime.

The focus should be on the right level of decomposition that enables rapid innovation, autonomous development/deployment without negatively impacting performance and increasing operational complexity. That’s how we used our own platform to build our dashboards and use the insights to find areas for further decomposition. If you want to see how the CloudMunch platform can help you in your microservices journey, start now by creating your team and adding your application.