A Micro-Services Checklist

  • The Approach — Greenfield and Brown-field
  • Handling Complex Business Processes — Orchestration
  • Handling Complex Business Processes — Choreography
  • Relational Databases Are Not a Panacea
  • Version your API and Messages (semantic all the way)
  • Developer Build and Release Effort
  • Observability — Service Correlation ID’s Are Imperative
  • Shared libraries cause coupling!
  • A fintech (Java-based) message archive, index, search platform for Petabyte scale - 2008;
  • A healthcare platform for drug modelling and reporting — 2011;
  • ERP platform (Java-based) to support eCommerce applications (web/mobile) - 2013;
  • Several (Javascript/Node.js, Python and Java) platforms in the mar-tech, ad-tech, fintech, healthcare platform space - 2016 onwards.

Monolith vs Services

There’s absolutely nothing wrong with building a monolith — in some situations it may actually be better if you’re a team of 1–10 people:

  • Less operational overhead in terms of managing source code in a VCS (think git clone, branch operations, running build commands)
  • A reduced set of components to worry about in a production operations environment;
  • A structure that’s easier to navigate (architectural concerns aside), debug and reason about in a development environment (although you need big developer machines with lots of RAM);
  • Easier to build for less experienced teams with less room to make mistakes around concepts you might not have experience with (orchestration etc…).
  • Flexibility with multiple components written in different languages, frameworks and libraries. Bear in mind here, however the implication that new developers have to be polyglots.
  • Smaller components that you can build and deploy in a quicker manner;
  • Independence which means you can scale specific services out in a more cost-effective manner;
  • Reduced performance profiles — think about memory usage (i.e big heap sizes with JVM’s), CPU and I/O.
  • Increased reliability — if one service fails, it doesn’t take everything down, but other services will need to be resilient to other components failed.

Micro-services Checklist

What do we need to consider when we’re building micro-services.

The Approach — Greenfield and Brown-field

There are a few approaches to building a green-field application in a micro-services approach:

  • Build services out bottom-up in the smallest possible way — services do one-thing;
  • Start with a monolith and split into a few services;
  • Do some analysis with a white-board;
  • Identify the first three services you would separate;
  • Look at the dependencies, how you would break them.

Handling Complex Business Processes — Orchestration

You can’t do everything synchronously with REST or with RPC-style. Why? Well, it’s fine for simple services where one service talks to another. However, when you have to call multiple services to do something then it becomes problematic. Take a POS system and placing an order, you would have to:

  • Create a contact record for the customer purchasing (new and existing accounts);
  • Lookup the product that needs to be purchased;
  • Check inventory for the item to ensure it’s in-stock — decrement inventory;
  • Create an order with several order line items;
  • Take payment for the item;
  • Fulfill and dispatch the order via your logistics system;
  • Send invoice amount to your accounting system.
  • Handle this operationally by flagging errors to a team who can then intervene manually to sort the problem out.
  • Take the transactional approach and attempt to roll everything back — that also introduces further complexity and required error handling, however.
  • Distributed transaction management is slow, doesn’t scale, and is expensive.
  • Orchestration — tell each service what to do synchronously;
  • Choreography — broadcast an event to each service and have it do what it needs to do;
  • Maintain a list of states, a workflow, and a set of transitions for the given business process;
  • As each step is completed/failed, mark the state as complete in your workflow or retry accordingly.

Handling Complex Business Processes — Choreography

We’ve covered one of the problems with synchronous operations above. In some cases, asynchronous operations may be a better way to do things, especially if you want to notify several services about a change without coupling a service to them directly. Instead, we can send events (Create Order) and have services react to this by carrying out what they need to do, i.e. fulfilling their part of the business process.

Relational Databases Are Not a Panacea

Relational databases are not the only solution for your services. In fact, they might be wholly unsuited to the problem at hand. They might work well for a warehouse system — fine. However, for CRM it’s not a great choice, especially if you need to run complex queries with lots of filters.

Version your API and Messages (semantic all the way)

You have to version your API right? It’s a sensible thing to do, but you will also want to version your messages in your message queues as well.

Developer Build and Release Effort

If you have a multi-repository/polyrepo setup, then multiple services are going to be painful without tooling. Think about:

  • git clone
  • git branch
  • make change in this service (and dependent ones if that’s your situation)
  • build the service
  • change version number
  • git commit and push

Observability — Service Correlation ID’s Are Imperative

Distributed tracing between lots of services requires you to piece together logs from those services. Correlation ID’s are invaluable here if you’re doing micro-services. We just need a unique identifier that we include in the log information relating to the user and the business process.

Shared libraries cause coupling!

You have a common library that’s shared across all services. It may be utility classes, or it may be a common set of domain classes. Split these into small libraries. Don’t be tempted to have one single acme-commons library that’s shared. Whenever you want to change it, you have to change everything that references it! You might want to relax your approach here to share everything.

Pragmatic Approach to Conway’s Law (Services > Teams)

Design your teams around your services they say. Well, that’s all good, but if you have 37 services and 15 developers it’s a little harder. Not everyone has the capacity to split services directly to teams. You might need to have one team own multiple services if you don’t have enough developers, or indeed own specific business processes.

Service Mapping

Big up-front design sucks — sure, but consider the services you might need and document them as part of your architecture guild as you discover and evolve them. I’ve published a simple service-canvas project on Github here:

  • Capabilities — what capabilities this service has;
  • Commands — both synchronous and asynchronous for this service
  • Queries — what queries this exposes (read operations)
  • Published Events — what events this emits
  • Non Functional Requirements — uptime, throughput and various SRE principles;
  • Observability — key metrics for this service;
  • Dependencies — what this invokes downstream and what events this service subscribes to.

In Conclusion

You learn a lot from your first micro-service experience — but walking into it without understanding the above items is a mistake.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store