Introduction to Microservices Patterns
Types of Monolith Applications (1) A) The Single Process Monolith: ● All code is packaged into a single deployable process. ● All data are stored in one single DB.
Types of Monolith Applications (2) B) The Modular Monolith ● Still single process, one deployable service. ● The code inside the process is broken down into modules.
Types of Monolith Applications (3) C) The Distributed Monolith ● Has all the drawbacks of both monolith and distributed systems ● Contains multiple services ● Whole ecosystem should be deployed together. ● Require changes everywhere in the services. ● Needs deploy coordination. ● Highly coupled.
Advantages of monoliths: 1. Simpler deployment topology, one deployable file. 2. ACID power – strongly data consistency. 3. Simplify code reuse. 4. Simplify architecture. Disadvantages of monoliths: 1. Difficult to scale. 2. Large scope for developer to familiarise. 3. Development is slow. 4. Lack of isolation and reliability. 5. Long time to test and deploy. 6. Lack of innovation. Monolith Applications
What are microservices? (1) Term: Microservices are small, autonomous, independently deployable services that function together to implement a business domain. Goal: Accelerate software development by enabling CI / CD and improve scaling issues. Main characteristics: - Own their own data. - Modeled around a business domain (DDD).
What are microservices? (2) Microservices Advantages: 1. Highly maintainable and testable. 2. Independently scalable. 3. Independently deployable. 4. Loosely coupled. 5. Being technology agnostic. 6. Faster development. Microservices Disadvantages: 1. Architecture the entire system is harder. 2. Introduce complexities of distributed systems (data consistency, lack of ACID) . 3. Need of cross-services queries to retrieve data from multiple services.
Challenge: Microservices and Databases ● Each service should own its own data, have its own database ● Service’s database should be accessed only by owner service and not from other services. ● Avoid shared databases - makes sense only for static data e.g. postCodes. ● We lose ACID power, as multiple databases are involved for a business use case. ● Introduces complexity on data consistency, as enforces eventually consistency.
Challenge: Clients access Microservices We need to figure out how clients will be able to use these services. Let's have a look at the some options: 1. Direct Client-to-Microservice Communication. 2. API Gateway. 3. Backend for frontend (BFF).
Pattern: Direct Client-to-Microservice Communication Make requests to each of the microservices directly. Benefits: ● Easy to implement Drawbacks: ● Higher latency leads to poor user experience. ● Mismatch between the needs of the client and the MS APIs. ● Difficult to refactor the microservices.
Pattern: API Gateway Benefits 1. Hides from the clients from how the application is divided into microservices. 2. Responsible for request routing. 3. Reduces the number of requests / roundtrips. 4. Composition. 5. Requests aggregation. 6. Protocol translation. Drawbacks 1. Increased complexity – must be developed, deployed and managed. 2. Availability issues. 3. Another point of failure
Features of API Gateway 1. Handling partial failure using the Circuit breaker pattern 2. Limiting the number of outstanding requests from a client to a service 3. Network timeouts 4. Provide fallbacks
Pattern: Backends for frontends (BFF) Benefits: ● Leading to high development velocities – as BFFs are client specific. ● Client applications are protected from API changes in downstream services. ● Dedicated Gateway for each client. Drawbacks: ● Duplication of code
Challenge: Inter-process communication one-to-one one-to-many Synchronous Request / Response - Asynchronous Asynchronous Request / Response One way notification Publish / Subscribe Publish / Async responses
RESTful APIs Benefits: 1. HTTP is simple and familiar. 2. Supports request / response style communication Drawbacks: 1. Blocking 2. Coupling 3. Cascading failures / Error Handling 4. Lacks replayability
Asynchronous Messaging Two types of async messaging: ● Brokerless ● Broker-based (Kafka, RabbitMQ, AWS kinesis…) The message represents a change in state, which is triggered when a user or service performs an action.
Brokers ● Point to Point (1-to-1): message is sent from one producer to a consumer via a queue (e.g. AWS SQS). Can be one or more consumers, listening on this queue but only one of them will be get the message. ● Publish/Subscribe (1-to-many): message is sent from one producer to multiple consumers/subscribers via a topic (e.g. Kafka, AWS Kinesis). The subscribers may or may not acknowledge the published message
Event-Driven Architecture (EDA) (1) EDA is an architecture design where a service is executed in response of receiving one or more events. Messages are triggered when a user or service performs an action and are emitted via topics / queues. ● Services communicate with events, and with APIs where is required. ● Services can produce and consume events. ● Event logs (messages) are the backbone of the system not the data ● Data is eventually consistent
Event-Driven Architecture (EDA) (2) Benefits of EDA: ● Loose coupling ● Flexibility ● Message buffering ● Resiliency ● Replayability ● Implementation of transactions that span multiple services and provide eventual consistency ● Enables an application to maintain materialized views Drawbacks of EDA: ● Potential single point of failure ● Learning curve ● Losing events if supports at-most- once delivery. ● Events ordering ● More difficult to design ecosystem
Event-Driven Architecture (EDA) (3) Here is an example of EDA: ● Sources / producers emit the events to event broker. ● There is a stream processing - this is different based on broker, eg kafka has the kstreams and ksql. ● Consumers are registered to specific topics / streams and consume events. ● Can have a external database where we can archive data, otherwise we can store them inside the broker
Challenge: Cross-service queries We want to get data from service A to service B: 1. Direct HTTP request from A to B 2. Create new aggregator service 3. Creating replication of the data
Challenge: Distributed transactions (1) How we keep consistency as we have multiple DBs? ❖ Monolith: One database – We have the solution of transaction (ACID) ❖ Microservices: Multiple databases - Distributed databases ➢ How to maintain a transaction’s automaticity? ➢ How to manage the transaction isolation level for concurrent requests?
Challenge: Distributed transactions (2) Let's have a look at the some options: 1. 2PC transactions. 2. Sagas.
Challenge: Distributed transactions (3) - 2PC transactions Two-phase commit (2PC) protocol: ● Prepare phase (Phase 1) ● Commit phase (Phase 2) Drawbacks: ● 2PC is not a viable option in modern applications, because of CAP theory. ● Does not scale. ● Most NoSQL databases, do not support 2PC
Challenge: Distributed transactions (3) - Sagas Sagas are sequence of local transactions. Each local transaction updates the database and publishes a message. If a local transaction fails, saga executes a series of compensating transactions to undo changes. Benefits: ● Maintain data consistency across multiple microservices without tight coupling (BASE) ● Perform better compared to 2PC. ● Offer no single point of failure. ● Keep the overall state of the transaction eventually consistent. Drawbacks: ● Difficult to implement, when a lot of services.
Challenge: Achieving atomicity publishing event and update database A service wants to update the database and publish events. The database update and event publishing must be atomic to avoid data inconsistencies and bugs. Possible Solutions: ● Outbox pattern using Polling. ● Outbox pattern and CDC using transaction logs. ● Event sourcing
Pattern 1: Outbox Table and Polling ● Make insert / update of the domain model to DB on a transaction (atomic). ● Add an insert on a new outbox table as part of the local transaction. ● Polling the DB for new events and fire event to message broker and mark them as published. Drawbacks: ❖ Polling the database can be expensive – consume a lot of db resources. ❖ Polling works well at low scale.
Pattern 2: Outbox Table and CDC ● Make insert / update of the domain model to DB on a transaction (atomic). ● Add an insert on a new outbox table as part of the local transaction. ● Read from generated a transaction log (CDC, like Debezium). Benefits: ❖ No distributed mechanism need. ❖ The service publishes domain events. Drawbacks: ➢ Might publish a message more than once (at- least-once). ➢ Some DBs does not support CDC.
Pattern 3: Event Sourcing ● Events are stored in an event store. ● Every state change is captured as an event and stored in sequence. ● Have one source of truth (event store) ● The event store emits events to all interested subscribers. ● By subscribing to events, you get an evolving copy of the object’s state. ● Reliable audit log.
General rules to managing data (1) ● Each service manages its own data / database. ● Embrace eventual consistency where possible. ● When you need strong consistency guarantees, one service may represent the source of truth for a given entity. ● If you need strong consistency among some services, rethink how we split services so the entities that should be consistent stay in one service. ● Store only the data that a service needs.
General rules to managing data (2) ● Enforce EDA and event sourcing style. Can be used to construct a materialized view from events which is suitable for querying. ● Try to eliminate sync communication among inter services communication. Try to enforce async and emit an event. ● Use HTTP when client triggers API GW / BFF. ● Even if we need data that belongs to other service, avoid to rely on sync requests (cross-service requests), but start using materialized views (local tables read-only) using EDA and eventual consistency ● The important rule is to try to avoid have synchronous dependencies between your services.
References ● Microservice Patterns: With examples in Java by Chris Richardson (https://microservices.io/) ● Monolith To Microservices by Sam Newman (https://samnewman.io/books/monolith-to-microservices/) ● Building Microservices by Sam Newman (https://samnewman.io/books/building_microservices/) ● NET Microservices Architecture for Containerized NET Applications (https://docs.microsoft.com/en- us/dotnet/architecture/microservices/) ● Designing and Deploying Microservices by NGINX (https://www.nginx.com/resources/library/designing- deploying-microservices/) ● Designing Distributed Systems by Brendan Burns ● Reliable Microservices Data Exchange With the Outbox Pattern (https://debezium.io/blog/2019/02/19/reliable-microservices-data-exchange-with-the-outbox-pattern/) ● Distributed transactions management by IBM (https://developer.ibm.com/depmodels/microservices/articles/use-saga-to-solve-distributed-transaction- management-problems-in-a-microservices-architecture) ● Managing Data in Microservices (https://www.youtube.com/watch?v=E8-e-3fRHBw) ● Creating event-driven microservices (https://www.youtube.com/watch?v=ksRCq0BJef8) ● Decomposition to MS (https://www.youtube.com/watch?v=64w1zbpHGTg) ● Data consistency into MS (https://www.youtube.com/watch?v=CFdPDfXy6Y0) ● Azure Data considerations for microservices (https://docs.microsoft.com/en- us/azure/architecture/microservices/design/data-considerations) ● Designing event driven systems by Ben Stopford (https://www.confluent.io/designing-event-driven-systems/)
Contact Info ● Arconsis: ○ Website: https://www.arconsis.com ○ Github: https://github.com/arconsis ● Dimos Botsaris: ○ Website: https://www.eldimious.com/ ○ Github: https://github.com/eldimious ○ Email: botsaris.d@gmail.com
Thank you!

Introduction to Microservices Patterns

  • 1.
  • 3.
    Types of MonolithApplications (1) A) The Single Process Monolith: ● All code is packaged into a single deployable process. ● All data are stored in one single DB.
  • 4.
    Types of MonolithApplications (2) B) The Modular Monolith ● Still single process, one deployable service. ● The code inside the process is broken down into modules.
  • 5.
    Types of MonolithApplications (3) C) The Distributed Monolith ● Has all the drawbacks of both monolith and distributed systems ● Contains multiple services ● Whole ecosystem should be deployed together. ● Require changes everywhere in the services. ● Needs deploy coordination. ● Highly coupled.
  • 6.
    Advantages of monoliths: 1.Simpler deployment topology, one deployable file. 2. ACID power – strongly data consistency. 3. Simplify code reuse. 4. Simplify architecture. Disadvantages of monoliths: 1. Difficult to scale. 2. Large scope for developer to familiarise. 3. Development is slow. 4. Lack of isolation and reliability. 5. Long time to test and deploy. 6. Lack of innovation. Monolith Applications
  • 7.
    What are microservices?(1) Term: Microservices are small, autonomous, independently deployable services that function together to implement a business domain. Goal: Accelerate software development by enabling CI / CD and improve scaling issues. Main characteristics: - Own their own data. - Modeled around a business domain (DDD).
  • 8.
    What are microservices?(2) Microservices Advantages: 1. Highly maintainable and testable. 2. Independently scalable. 3. Independently deployable. 4. Loosely coupled. 5. Being technology agnostic. 6. Faster development. Microservices Disadvantages: 1. Architecture the entire system is harder. 2. Introduce complexities of distributed systems (data consistency, lack of ACID) . 3. Need of cross-services queries to retrieve data from multiple services.
  • 9.
    Challenge: Microservices andDatabases ● Each service should own its own data, have its own database ● Service’s database should be accessed only by owner service and not from other services. ● Avoid shared databases - makes sense only for static data e.g. postCodes. ● We lose ACID power, as multiple databases are involved for a business use case. ● Introduces complexity on data consistency, as enforces eventually consistency.
  • 10.
    Challenge: Clients accessMicroservices We need to figure out how clients will be able to use these services. Let's have a look at the some options: 1. Direct Client-to-Microservice Communication. 2. API Gateway. 3. Backend for frontend (BFF).
  • 11.
    Pattern: Direct Client-to-Microservice Communication Makerequests to each of the microservices directly. Benefits: ● Easy to implement Drawbacks: ● Higher latency leads to poor user experience. ● Mismatch between the needs of the client and the MS APIs. ● Difficult to refactor the microservices.
  • 12.
    Pattern: API Gateway Benefits 1.Hides from the clients from how the application is divided into microservices. 2. Responsible for request routing. 3. Reduces the number of requests / roundtrips. 4. Composition. 5. Requests aggregation. 6. Protocol translation. Drawbacks 1. Increased complexity – must be developed, deployed and managed. 2. Availability issues. 3. Another point of failure
  • 13.
    Features of APIGateway 1. Handling partial failure using the Circuit breaker pattern 2. Limiting the number of outstanding requests from a client to a service 3. Network timeouts 4. Provide fallbacks
  • 14.
    Pattern: Backends forfrontends (BFF) Benefits: ● Leading to high development velocities – as BFFs are client specific. ● Client applications are protected from API changes in downstream services. ● Dedicated Gateway for each client. Drawbacks: ● Duplication of code
  • 15.
    Challenge: Inter-process communication one-to-oneone-to-many Synchronous Request / Response - Asynchronous Asynchronous Request / Response One way notification Publish / Subscribe Publish / Async responses
  • 16.
    RESTful APIs Benefits: 1. HTTPis simple and familiar. 2. Supports request / response style communication Drawbacks: 1. Blocking 2. Coupling 3. Cascading failures / Error Handling 4. Lacks replayability
  • 17.
    Asynchronous Messaging Two typesof async messaging: ● Brokerless ● Broker-based (Kafka, RabbitMQ, AWS kinesis…) The message represents a change in state, which is triggered when a user or service performs an action.
  • 18.
    Brokers ● Point toPoint (1-to-1): message is sent from one producer to a consumer via a queue (e.g. AWS SQS). Can be one or more consumers, listening on this queue but only one of them will be get the message. ● Publish/Subscribe (1-to-many): message is sent from one producer to multiple consumers/subscribers via a topic (e.g. Kafka, AWS Kinesis). The subscribers may or may not acknowledge the published message
  • 19.
    Event-Driven Architecture (EDA)(1) EDA is an architecture design where a service is executed in response of receiving one or more events. Messages are triggered when a user or service performs an action and are emitted via topics / queues. ● Services communicate with events, and with APIs where is required. ● Services can produce and consume events. ● Event logs (messages) are the backbone of the system not the data ● Data is eventually consistent
  • 20.
    Event-Driven Architecture (EDA)(2) Benefits of EDA: ● Loose coupling ● Flexibility ● Message buffering ● Resiliency ● Replayability ● Implementation of transactions that span multiple services and provide eventual consistency ● Enables an application to maintain materialized views Drawbacks of EDA: ● Potential single point of failure ● Learning curve ● Losing events if supports at-most- once delivery. ● Events ordering ● More difficult to design ecosystem
  • 21.
    Event-Driven Architecture (EDA)(3) Here is an example of EDA: ● Sources / producers emit the events to event broker. ● There is a stream processing - this is different based on broker, eg kafka has the kstreams and ksql. ● Consumers are registered to specific topics / streams and consume events. ● Can have a external database where we can archive data, otherwise we can store them inside the broker
  • 22.
    Challenge: Cross-service queries Wewant to get data from service A to service B: 1. Direct HTTP request from A to B 2. Create new aggregator service 3. Creating replication of the data
  • 23.
    Challenge: Distributed transactions(1) How we keep consistency as we have multiple DBs? ❖ Monolith: One database – We have the solution of transaction (ACID) ❖ Microservices: Multiple databases - Distributed databases ➢ How to maintain a transaction’s automaticity? ➢ How to manage the transaction isolation level for concurrent requests?
  • 24.
    Challenge: Distributed transactions(2) Let's have a look at the some options: 1. 2PC transactions. 2. Sagas.
  • 25.
    Challenge: Distributed transactions(3) - 2PC transactions Two-phase commit (2PC) protocol: ● Prepare phase (Phase 1) ● Commit phase (Phase 2) Drawbacks: ● 2PC is not a viable option in modern applications, because of CAP theory. ● Does not scale. ● Most NoSQL databases, do not support 2PC
  • 26.
    Challenge: Distributed transactions(3) - Sagas Sagas are sequence of local transactions. Each local transaction updates the database and publishes a message. If a local transaction fails, saga executes a series of compensating transactions to undo changes. Benefits: ● Maintain data consistency across multiple microservices without tight coupling (BASE) ● Perform better compared to 2PC. ● Offer no single point of failure. ● Keep the overall state of the transaction eventually consistent. Drawbacks: ● Difficult to implement, when a lot of services.
  • 27.
    Challenge: Achieving atomicitypublishing event and update database A service wants to update the database and publish events. The database update and event publishing must be atomic to avoid data inconsistencies and bugs. Possible Solutions: ● Outbox pattern using Polling. ● Outbox pattern and CDC using transaction logs. ● Event sourcing
  • 28.
    Pattern 1: OutboxTable and Polling ● Make insert / update of the domain model to DB on a transaction (atomic). ● Add an insert on a new outbox table as part of the local transaction. ● Polling the DB for new events and fire event to message broker and mark them as published. Drawbacks: ❖ Polling the database can be expensive – consume a lot of db resources. ❖ Polling works well at low scale.
  • 29.
    Pattern 2: OutboxTable and CDC ● Make insert / update of the domain model to DB on a transaction (atomic). ● Add an insert on a new outbox table as part of the local transaction. ● Read from generated a transaction log (CDC, like Debezium). Benefits: ❖ No distributed mechanism need. ❖ The service publishes domain events. Drawbacks: ➢ Might publish a message more than once (at- least-once). ➢ Some DBs does not support CDC.
  • 30.
    Pattern 3: EventSourcing ● Events are stored in an event store. ● Every state change is captured as an event and stored in sequence. ● Have one source of truth (event store) ● The event store emits events to all interested subscribers. ● By subscribing to events, you get an evolving copy of the object’s state. ● Reliable audit log.
  • 31.
    General rules tomanaging data (1) ● Each service manages its own data / database. ● Embrace eventual consistency where possible. ● When you need strong consistency guarantees, one service may represent the source of truth for a given entity. ● If you need strong consistency among some services, rethink how we split services so the entities that should be consistent stay in one service. ● Store only the data that a service needs.
  • 32.
    General rules tomanaging data (2) ● Enforce EDA and event sourcing style. Can be used to construct a materialized view from events which is suitable for querying. ● Try to eliminate sync communication among inter services communication. Try to enforce async and emit an event. ● Use HTTP when client triggers API GW / BFF. ● Even if we need data that belongs to other service, avoid to rely on sync requests (cross-service requests), but start using materialized views (local tables read-only) using EDA and eventual consistency ● The important rule is to try to avoid have synchronous dependencies between your services.
  • 33.
    References ● Microservice Patterns:With examples in Java by Chris Richardson (https://microservices.io/) ● Monolith To Microservices by Sam Newman (https://samnewman.io/books/monolith-to-microservices/) ● Building Microservices by Sam Newman (https://samnewman.io/books/building_microservices/) ● NET Microservices Architecture for Containerized NET Applications (https://docs.microsoft.com/en- us/dotnet/architecture/microservices/) ● Designing and Deploying Microservices by NGINX (https://www.nginx.com/resources/library/designing- deploying-microservices/) ● Designing Distributed Systems by Brendan Burns ● Reliable Microservices Data Exchange With the Outbox Pattern (https://debezium.io/blog/2019/02/19/reliable-microservices-data-exchange-with-the-outbox-pattern/) ● Distributed transactions management by IBM (https://developer.ibm.com/depmodels/microservices/articles/use-saga-to-solve-distributed-transaction- management-problems-in-a-microservices-architecture) ● Managing Data in Microservices (https://www.youtube.com/watch?v=E8-e-3fRHBw) ● Creating event-driven microservices (https://www.youtube.com/watch?v=ksRCq0BJef8) ● Decomposition to MS (https://www.youtube.com/watch?v=64w1zbpHGTg) ● Data consistency into MS (https://www.youtube.com/watch?v=CFdPDfXy6Y0) ● Azure Data considerations for microservices (https://docs.microsoft.com/en- us/azure/architecture/microservices/design/data-considerations) ● Designing event driven systems by Ben Stopford (https://www.confluent.io/designing-event-driven-systems/)
  • 34.
    Contact Info ● Arconsis: ○Website: https://www.arconsis.com ○ Github: https://github.com/arconsis ● Dimos Botsaris: ○ Website: https://www.eldimious.com/ ○ Github: https://github.com/eldimious ○ Email: botsaris.d@gmail.com
  • 35.