1 of 58

Reactive Microservices

Matt Clement - @mallize

LifeWay IT

tech.lifeway.com @lifewaytech

2 of 58

Reactive Microservices

Matt Clement - @mallize

LifeWay IT - tech.lifeway.com - @lifewaytech

3 of 58

LifeWay

  • Much more than a bookstore
  • 150 employees in IT alone
  • Everything from back-office applications, big data, consumer applications, mobile applications, etc.
  • A lot of legacy systems… a lot

4 of 58

LifeWay

5 of 58

Evolutionary Architecture

  • Modularity and Loose Coupling
    • Separate along well defined boundaries
    • Not a ‘big ball of mud’
  • Organized around Business Capabilities
    • Domain Driven Design
  • Supports Experimentation
    • Canary releases
    • A/B testing
  • Bring the Pain Forward
    • Continuous Delivery (automate everything)
  • Last Responsible Moment
    • Allow the architecture to evolve

https://www.thoughtworks.com/insights/blog/microservices-evolutionary-architecture

6 of 58

Evolutionary Architecture

Microservices

&

Reactive Programming

7 of 58

Microservices

8 of 58

Microservices vs Monolithic

  • Component types
    • Client-side user interface
    • Database (often relational)
    • Server-side business logic
  • Pros
    • Simple Deployment
    • Run entire stack on a dev machine
  • Cons
    • Modules are deployed together (tight coupling)
    • Leaky abstractions
    • Vertical scaling only
    • Monoliths of monoliths

9 of 58

Microservices vs Service Oriented (SOA)

  • Component Types
    • Providers
    • Consumers
    • Transport/Translation (Enterprise Service Bus, ESB)
  • Pros
    • ‘Kind of’ Loosely Coupled
    • Reusability
    • Independent Scalability
  • Cons
    • Shared Data Model
    • Often used shared physical DB
    • Often deployed as distributed monoliths
    • Easy to have cascading failures

10 of 58

Microservices

Breaking down an application into a suite of small, well-defined services that are built around business capabilities, independently deployable and do not share their data model.

11 of 58

Built around business capabilities

  • Domain Driven Design is an architectural strategy focusing on the core domain of system or subsystem.
  • A domain is considered a bounded context. The internal model and behavior are not exposed.
  • Context maps and anti-corruption layers help keep the domains pure while allowing collaboration.
  • Ubiquitous Language - The shared language for business and code within a bounded context

12 of 58

Domain Driven Design

13 of 58

Independently Deployable

  • Each microservice should be able to deploy to production independent of other services
  • Continuous Integration, Continuous Delivery and Continuous Deployment
  • Backwards compatibility is a must
  • CDD - Consumer Driven Contracts help identify breaking changes before deploying.

14 of 58

Share Nothing

SOA is built on the concept of a share-as-much- as-possible architecture style, whereas microservices architecture is built on the concept of a share-as-little-as-possible architecture style.

~Mark Richards

  • Reuse through creating enterprise capabilities
  • Microservices have their own database(s)
    • Document store for views
    • Graph for searching

15 of 58

Microservices Suggestions

API Gateways for client applications

16 of 58

Microservices Suggestions

Create facades in front of capabilities.

Allows for evolutionary architecture.

17 of 58

18 of 58

Microservices Suggestions

Create 12 factor apps (https://12factor.net/)

19 of 58

Microservices Prerequisites

  • DevOps mentality
    • Designing microservices goes beyond code. You have to consider the environment that you are deploying to. How do you leverage the capabilities of your cloud provider?
    • Service Discovery, HA, Security, etc
  • Continuous Delivery pipeline
  • Monitoring and Log aggregation

20 of 58

Microservices Prerequisites - Build Pipeline

Each microservice should have it's own build pipeline in GoCD. An example build pipeline is shown in the diagram below. Variations of this pipeline will exist for different services but the required pipeline steps are:

  • Unit Tests
  • Build Artifact
  • Automated deploy to an dev/ci environment
  • Functional tests (full regression can happen in a separate build step if needed)
  • Automated Stage deploy
  • Load tests
  • Consumer-Driven Contract tests (1-N)

21 of 58

22 of 58

Microservices

Breaking down an application into a suite of small, well-defined services that are built around business capabilities, independently deployable and do not share their data model.

23 of 58

Reactive Programming

http://www.reactivemanifesto.org

24 of 58

Responsive

  • The system responds in a timely manner if at all possible.
  • Problems may be detected quickly and dealt with effectively.
  • Rapid and consistent response times, establishing reliable upper bounds so they deliver a consistent quality of service.
  • This consistent behaviour in turn simplifies error handling, builds end user confidence, and encourages further interaction.

25 of 58

Resilient

  • Stays responsive in the face of failure.
  • Resilience is achieved by replication, containment, isolation and delegation.
  • Failures are contained within each component, isolating components from each other and thereby ensuring that parts of the system can fail and recover without compromising the system as a whole.
  • Recovery of each component is delegated to another (external) component and high-availability is ensured by replication where necessary.
  • The client of a component is not burdened with handling its failures.

26 of 58

Elastic

  • Stays responsive under varying workload.
  • Can react to changes in the input rate by increasing or decreasing the resources.
  • No contention points or central bottlenecks, resulting in the ability to shard or replicate components.
  • Support predictive, as well as Reactive, scaling algorithms by providing relevant live performance measures.
  • Achieve elasticity in a cost-effective way on commodity hardware and software platforms.

27 of 58

Message Driven

  • Rely on asynchronous message-passing
  • Enables load management, elasticity, and flow control by shaping and monitoring the message queues in the system and applying back-pressure when necessary.
  • Location transparency
  • Non-blocking communication allows recipients to only consume resources while active, leading to less system overhead.

28 of 58

Reactive Microservices

Jonas Bonér lists the following as characteristics of Reactive Microservices

  • Isolation
  • Act Autonomously
  • Do one thing and do it well
  • Own your state
  • Embrace Asynchronous Message-Passing
  • Stay Mobile, but Addressable

29 of 58

Isolation

Isolation has a huge impact on design and should be considered at the start of designing a system.

Conway’s Law

"Any organization that designs a system (defined more broadly here than just information systems) will inevitably produce a design whose structure is a copy of the organization's communication structure." ~ Melvin Conway

Good or bad is a matter of perspective. Create teams around suites of services or capabilities.

30 of 58

Isolation

Isolation allows us to reduce the blast radius of errors. We don’t want cascading failures to take down our system.

31 of 58

Isolation

If service E goes down...

32 of 58

Isolation

We don’t want all other services to be affected

33 of 58

Isolation

Similar to ship bulkheading

34 of 58

Isolation

Similar to ship bulkheading

35 of 58

Isolation - How?

Circuit Breaker Pattern

36 of 58

Isolation - Circuit Breaker Pattern

A degraded experience is better than no experience.

37 of 58

Isolation

In a highly distributed system, synchronous API calls are dangerous.

38 of 58

Isolation

Temporally decouple components through message driven communication.

39 of 58

Message Driven at LifeWay

  • Enterprise Events - Streaming
    • Used to communicate between bounded contexts
    • Built on Kafka
    • Domains Subscribe to Events
    • Temporally decouple Microservices / Bounded Contexts
  • CQRS
    • Command Query Responsibility Segregation
    • Different Read model from Write model
      • We use event sourcing for our writes
      • Several read models possible
        • Denormalized views
        • Search indexes
    • Commands mutate state and do not return data
    • Queries return data but do not mutate state

40 of 58

Message Driven - CQRS

“CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation: a command is any method that mutates state and a query is any method that returns a value). —Greg Young

41 of 58

Message Driven - CQRS

Reason for segregation

  • Large imbalance of reads and writes
  • Command side involves complex business logic
  • Read side should be optimized for reads
  • Write side should be optimized for writes
  • One model does neither very well

42 of 58

Message Driven - CQRS

  • Traditional read/write domain models have an impedance mismatch between the persistence and actual model.
  • ORM (object relational mapping) tools try to ease this pain, but can become very complex.
  • A SQL database in 5th normal form doesn’t map to a flat domain model.

43 of 58

Message Driven - CQRS - Event Sourcing

Event Sourcing - Storing changes as a set of event logs rather than just the current state. The current state is derived from replaying the events.

44 of 58

Message Driven - CQRS - Event Sourcing

Benefits of using event sourcing for the write side

  • You can reconstruct the state of your domain at any point in history
  • Events are immutable ‘facts’. You can not change them. You can only compensate for errors (much like real life communication).
  • Free audit log
  • Events can be forwarded so that 1-N event handlers can take action on the events
    • The most common is a view handler which creates a denormalized view of the ‘current state’.
  • You can create new views that business didn’t know they wanted.

45 of 58

CQRS

46 of 58

CQRS

{ event : “ItemAddedToCart”,

sku : “sku123”,

quantity : 2 }

{ items : [

{sku : “sku123”, quantity : 2},

{sku : “sku456”, quantity : 1}

] }

{ event : “ItemRemovedFromCart”,

sku : “sku123”,

quantity : 1 }

{ items : [

{sku : “sku456”, quantity : 1}

] }

{ event : “ItemAddedToCart”,

sku : “sku456”,

quantity : 1 }

{ items : [

{sku : “sku123”, quantity : 1},

{sku : “sku456”, quantity : 1}

] }

{ event : “ItemAddedToCart”,

sku : “sku123”,

quantity : 1 }

{ items : [

{sku : “123”, quantity : 1}

] }

Event Log Current State

47 of 58

CQRS end to end demo

https://www.smallgroup.com

48 of 58

Procedural REST Calls

49 of 58

Async Message Passing (Events)

50 of 58

What about transactions?

Saga - A finite state machine that’s state transitions are based on the events pertaining to a certain business process. Errors captured include invalid state transitions, timeouts and errors in messaging when orchestrating API calls.

Compensating events can be used to undo portions of a saga (similar to rolling back).

51 of 58

52 of 58

Message Driven

  • Embrace Eventual Consistency
    • Matter of ms normally
    • Create SLAs
    • Not always the best fit; stock trader apps
    • ATM Machines
    • Airlines
  • Resilient publishers
  • Resilient consumers
    • Pull model
    • Back pressure

53 of 58

Physical Architecture

  • Each service is deployed on separate isolated instances
  • Each service auto scales based on its load across multiple AZ’s.
  • Each service has in internal ELB for managing that service’s traffic

54 of 58

55 of 58

Scaling under 3x avg load

56 of 58

Latency under 3x load

57 of 58

Summary

Microservices provide the means for creating autonomous, single responsibility services that can provide quick turn around for a company's feature sets. Because of their limited scope of responsibility they are easy to implement, change and maintain.

Complexity is contextual. The complexity in microservices moves out of the services themselves and into their deployment strategy, communication patterns and HA strategy.

Reactive Programming provides guidelines for creating systems that are designed to handle failure, load and asynchronous communication.

58 of 58

Questions?

Twitter:

@mallize

@lifewaytech

GitHub: github.com/LifeWay

More Info: http://tech.lifeway.com/more-info/