Microservices - Why and What

An exploration of microservices architecture, its benefits, challenges, and implementation considerations in modern software development.

This article was originally published at drstarry.github.io.

Intro

While moving from a monolithic application towards microservices architecture, it's important to understand the motivation. This article will briefly discuss about the why and what.

I've attached the links for Martin Fowler's blog in referrence section, where he posts many useful articles related to microservices topic.

What is Best Practice

Sometimes it's hard to convince people to follow the so-called best practice. If best practice is only a set of conventions that we historically think that's a good way to do something, it's not a strong argument to force people to follow.

Moving from monolithic to microservices architecture, is the best practice to build softwares only under certain conditions, where we really feel the need to undertake this approach.

Monolith

Before we introduce any buzzwords, let's look at the natural way of building softwares -- developers work on a single codebase with some basic(manual) test/build/deploy pipeline. Everything works fine at this point.

When the team grows rappidly, it's frustrating to work on a single codebase. Imagine one bug in a single module will endup with rolling back the entire codebase and blocking other people's release. It's also easy to mess around with a single gaint repo, over the time, it's extremely hard to keep a good(modular) code structure. The million-line codebase also slows down the build/deploy cycle.

All these frustration lead people to find a better way to work together.

Definition of Microservice

In short, 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, which may be written in different programming languages and use different data storage technologies. -- James Lewis and Martin Fowler

Common Characteristics

The following characteristics are concluded by Martin Fowler:

  1. Componentization via Services
    • independently replacable
    • independently upgradeable
  2. Organized around Business Capabilities
  3. Products not Projects
  4. Smart endpoints and dumb pipes
  5. Decentralized Governance
  6. Decentralized Data Management
  7. Infrastructure Automation
  8. Design for failure
  9. Evolutionary Design

For some characteristics above, I want to add a few thoughts.

Decentralized Data Management

To explain, this aligns with one of my current employer's architecture tanents - Service should own their own data.

Shared database has some obvious disadvantages:

  1. it allows external parties to view and bind to internal implementation details
    • schema change is hard -- easy to break other services
    • shared API is very brittle -- requires a large amount of regression testing
    • no diversity in tech choices -- tho technologies/frameworks evolve really fast
  2. it's extremely hard to manipulate data
    • serivce(data) owner has no control -- no single source of truth
    • no one owns the associated logic -- duplicate and diverge, BOOM!
    • hard to mainten and scale -- a small change touch a million places

More complexities flow in when we need to consider cache invalidation etc. When service owns read and write of its own data, it's easier to define ownership and make collabertation more efficient.

Design for failure

Breaking down one gaint application into small pieces, means each piece has more external dependencies. [updated on Dec.27 2017]I recently added several fault injection tests to the service I'm working on. The main purpose of fault injection is to make sure -- services will be available when one or more (non-critical) dependencies are down.

Chaos Monkey is also a useful tool to test resiliency and recoverability of the service by intentionally disabling some production boxes.

Microservices and SOA

We've seen SOA (Service Oriented Architecture) decades ago, this is not a new term. There is no one way to define SOA. Briefly speaking, microservices is subset of SOA. Or you could say microservices is fine-grained SOA.

Currently, many people just use SOA for microservices archtecture.

Some Disadvantanges

The cost of adopting microservices architecture is also huge:

  • Embrace distribution -- distributed system brings a bunch of complexties, when services need to communicate via remote calls or async calls, it's hard.
  • Eventual consistency -- Strong consistency is hard to enforce when we need high availability. In microservices world, we must compromise on eventual consistency.
  • Slowness -- this side effect is the direct result from moving towards microservices because communicating through services boundries is more expensive than calling a library.
  • Operational overhead -- doesn't need to explain

Please refer to this post for the trade-offs of microservices.

Summery

Microservices is an architectural design pattern to help us build services with

  • Modular
  • Ease to deploy
  • Independent scalability
  • Technology diversity

It does not naturally apply to any stage of the development. When efficiency of multiple people working on a single application is really a big concern, that's the time you may want to consider moving towards microservices.

Reference

  1. Building Microservices: Designing Fine-Grained Systems
  2. Martin Fowler's blog
  3. GOTO 2014 • Microsevices • Martin Fowler