Randy Shoup talks about Microservices

·

4 min read


Modern Software Development

  • Organization := Small Teams
  • Practices := TDD and Continuous Delivery
  • Technology := Microservices
  • Culture := DevOps

Small "Service" Teams

  • Teams are aligned to Business Domains to give clear, well-defined area of responsibility.
  • Those teams are Cross-functional Teams that hold all skill sets needed to do the job.
  • Teams depend on other teams for supporting services, libraries, and tools.

Test-Driven Development

  • Tests help you go faster.
  • Tests make better code.
  • Tests make better systems.
  • Do it right (enough) the first time.
  • Right != Perfect. By 80/20 Rule, build the just right system at that moment and move on.
  • Basically there's no global bug tracking system. Bugs (or Backlogs) are not defects but new features we want to build.

"We don't have time to do it right!"
"Do you have time to do it twice?"

Continuous Delivery (CD)

  • Most applications deployed multiple times per day.
  • CD ensures more solid systems.
  • CD allows rapid experimentation.

DevOps

  • End-to-end Ownership. Team owns service from design to deployment until retirement.
  • Responsible for all aspects of software development: features, quality, performance, operations, maintenance.

You Build It, You Run It. - Werner Vogels

Microservices

Evolution to Microservices

  • eBay: Monolithic Perl -> Monolithic C++ (6.4M lines of code in single DLL. Hitting the limit of the number of methods per class which is 16K.) -> Java -> microservices
  • Twitter: Monolithic Rails -> JS / Rails / Scala -> microservices
  • Amazon: Monolithic Perl / C++ -> Java / Scala -> microservices

Usage of Microservices

  • Microservices are not for every company and not for every stage of company.
  • There was a eBay competitor that spent all the time building distributed system but no one have heard about that company.

First Law of Distributed Object Design: Don't distribute your objects! - Martin Fowler
If you don't end up regretting your early technology decisoins, you probably over-engineered.

Microservices

  • Single-purposed
  • Simple, well-defined interface
  • Modular and independent
  • Isolated persistence

Microservices are nothing more than SOA (Service Oriented Architecture) done properly.


Microservice Persistence

  • Approach 1: Operate your own data store
  • Approach 2: Use a persistence service
  • Only external access to data store is through published service interface.

Events as First-Class Construct

  • Event is a significant change in state.
  • Traditional 3-tier system
    • Presentation -> interface
    • Application -> business logic (stateless)
    • Persistence -> database
  • Fourth fundamental building block
    • State changes -> events
  • Events represent how the real world works

Microservices and Events

  • Events are a first-class part of a service interface
  • A service interface includes any mechanism for getting data in or out of the service:
    • Synchronous request-response (REST, gRPC, ...)
    • Events the svc produces
    • Events the svc consumes
    • Bulk reads and writes (ETL)

Extracting Microservices

  • Problem: Monolithic shared DB
  • Solution: Decouple applications and services
    • Step 1: Create a service
    • Step 2: Applications use the service
    • Step 3: Move data to private database
    • Step 4: Rinse and Repeat

Microservice Techniques

Shared Data

  • Problem: Where does shared data go in a microservices world?
  • Principle: There is only one service that r/w informations. Every other copy is a read-only, non-authoritative cache.

Approach 1: Synchronous Lookup

image.png

Approach 2: Async event + local cache

image.png

  • Customer-service sends address-updated event when customer address changes.
  • Fulfillment-service consumes event and caches current address.

Approach 3: Shared metadata library

image.png

  • Read-only metadata, basically immutable, e.g., schemas, colors, fabrics, US States, etc.

Joins

  • Problem: Splitting the data into separate services makes joins very hard.

Approach 1: Join in Client Application

  • Join at real-time.
  • Best when 1-to-n join (customer : orders)
  • Many common systems do this.

Approach 2: Materialize the View

image.png

  • When things are massive and too costly to join at real-time.
  • Listen to events from item-service and order-feedback-service.
  • Maintain denormalized join of items and order feedback in local storage. Join at real-time.
  • Many common systems do this. E.g. most NoSQL approches, "materialized view" in db system, search engines, analytic systems, log aggregators.

Workflows and Sagas

  • Problem: Splitting data across services makes transactions very hard.
  • Transaction -> Saga: model the transaction as a state machine of atomic events.
  • Roll back by applying compensating operations in reverse.
  • Many common systems do this. E.g. payment processing, expense approval, any multi-step workflow.
  • Ideal for using Funcions as a Service ("serverless"). Very lightweight and stateless.