building and deploying microservices with event sourcing
play

Building and deploying microservices with event sourcing, CQRS and - PowerPoint PPT Presentation

Building and deploying microservices with event sourcing, CQRS and Docker Chris Richardson Author of POJOs in Action Founder of the original CloudFoundry.com @crichardson chris@chrisrichardson.net http://plainoldobjects.com


  1. Building and deploying microservices with event sourcing, CQRS and Docker Chris Richardson Author of POJOs in Action Founder of the original CloudFoundry.com @crichardson chris@chrisrichardson.net http://plainoldobjects.com http://microservices.io @crichardson

  2. Presentation goal Share my experiences with building and deploying an application using Scala, functional domain models, microservices, event sourcing, CQRS, and Docker @crichardson

  3. About Chris @crichardson

  4. About Chris Founder of a buzzword compliant (stealthy, social, mobile, big data, machine learning, ...) startup Consultant helping organizations improve how they architect and deploy applications using cloud, micro services, polyglot applications, NoSQL, ... Creator of http://microservices.io @crichardson

  5. For more information https://github.com/cer/event-sourcing-examples http://microservices.io http://plainoldobjects.com/ https://twitter.com/crichardson @crichardson

  6. Agenda Why build event-driven microservices? Overview of event sourcing Designing microservices with event sourcing Implementing queries in an event sourced application Building and deploying microservices @crichardson

  7. Traditional application architecture WAR/EAR ACID Spring MVC Banking HTML REST/JSON Accounts Browser/ Load RDBMS Client balancer Spring Transfers Hibernate Customers Simple ... develop test Tomcat deploy scale @crichardson

  8. Limitations of the monolithic architecture Intimidates developers Obstacle to frequent deployments Overloads your IDE and container Obstacle to scaling development Modules having conflicting scaling requirements Requires long-term commitment to a technology stack @crichardson

  9. Apply the scale cube Y axis - functional decomposition Scale by g n splitting r i n a o l i m i different things t i t i s r a g p n a i t t t a i s l p d g s n - y i h s b t i x e a l a Z c S X axis - horizontal duplication @crichardson

  10. Use a microservice architecture Standalone services Banking UI Account Management MoneyTransfer Service Management Service Account MoneyTransfer Database Database @crichardson

  11. Limitations of a single relational database Scalability Distribution Schema updates O/R impedance mismatch Handling semi-structured data @crichardson

  12. Use a sharded relational database @crichardson

  13. Use NoSQL databases Avoids the limitations of RDBMS For example, text search ⇒ Solr/Cloud Search social (graph) data ⇒ Neo4J highly distributed/available database ⇒ Cassandra ... @crichardson

  14. Different modules use different types of databases @crichardson IEEE Software Sept/October 2010 - Debasish Ghosh / Twitter @debasishg

  15. But this results in distributed data management problems @crichardson

  16. Example #1 - SQL + Text Search engine Application MySQL ElasticSearch Product #1 Product #1 How to maintain consistency without 2PC? @crichardson

  17. Example #2 - Cassandra main table <=> index table Denormalized Application view Cassandra Main Table Index Table How to maintain consistency without 2PC? @crichardson

  18. Example #3: Money transfer Account Management MoneyTransfer Service Management Service Account MoneyTransfer Database Database Account #1 Money Transfer Account #2 How to maintain consistency without 2PC? @crichardson

  19. Event-based architecture to the rescue Components (e.g. services) publish events when state changes Components subscribe to events Maintains eventual consistency across multiple aggregates (in multiple datastores) Synchronize replicated data @crichardson

  20. Event-driven synchronization: SQL + Text Search engine create product Catalog Service Search Service Product Product Insert Index Doc Created Created MySQL Message Bus ElasticSearch Product #1 Product #1 @crichardson

  21. Eventually consistent money transfer transferMoney() MoneyTransferService AccountService MoneyTransfer MoneyTransfer MoneyTransfer Account Account Account Account fromAccountId = 101 fromAccountId = 101 fromAccountId = 101 id = 101 id = 101 id = 202 id = 202 toAccountId = 202 toAccountId = 202 toAccountId = 202 balance = 250 balance = 195 balance = 125 balance = 180 amount = 55 amount = 55 amount = 55 state = INITIAL state = DEBITED state = COMPLETED Subscribes to: Publishes: AccountDebitedEvent Subscribes to: publishes: AccountCreditedEvent AccountDebitedEvent MoneyTransferCreatedEvent MoneyTransferCreatedEvent AccountCreditedEvent DebitRecordedEvent DebitRecordedEvent Message Bus @crichardson

  22. To maintain consistency a service must atomically publish an event whenever a domain object changes @crichardson

  23. How to atomically update the datastore and publish event(s)? Use 2PC Use datastore as a message queue Guaranteed atomicity BUT 1. Update database: new entity state & event Need a distributed transaction manager 2. Consume event & mark event as consumed Database and message broker must support 2PC Eventually consistent mechanism Impacts reliability See BASE: An Acid Alternative, http://bit.ly/ebaybase Not fashionable • BUT Tangled business logic and 2PC is best avoided event publishing code • Difficult to implement when using a NoSQL database :-(

  24. Agenda Why build event-driven microservices? Overview of event sourcing Designing microservices with event sourcing Implementing queries in an event sourced application Building and deploying microservices @crichardson

  25. Event sourcing For each aggregate: Identify (state-changing) domain events Define Event classes For example, Account: AccountOpenedEvent, AccountDebitedEvent, AccountCreditedEvent ShoppingCart: ItemAddedEvent, ItemRemovedEvent, OrderPlacedEvent @crichardson

  26. Persists events X NOT current state Account table 101 450 Account Event table balance 101 901 AccountOpened 500 open(initial) debit(amount) 101 902 AccountCredited 250 credit(amount) 101 903 AccountDebited 300 @crichardson

  27. Replay events to recreate state Events AccountOpenedEvent(balance) AccountDebitedEvent(amount) AccountCreditedEvent(amount) Account balance @crichardson

  28. Two actions that must be atomic Before: update state + publish events Now: persist (and publish) events Single action that can be done atomically @crichardson

  29. Aggregate traits Apply event returning updated Aggregate Map Command to Events @crichardson

  30. Account - command processing Prevent overdraft @crichardson

  31. Account - applying events Immutable @crichardson

  32. Request handling in an event-sourced application Microservice A pastEvents = findEvents(entityId) new() applyEvents(pastEvents) HTTP Event Account Handler Store newEvents = processCmd(SomeCmd) saveEvents(newEvents) @crichardson

  33. Event Store publishes events - consumed by other services Microservice B update() subscribe(EventTypes) Aggregate publish(event) Event Event Subscriber Store update() publish(event) NoSQL materialized view @crichardson

  34. Optimizing using snapshots Most aggregates have relatively few events BUT consider a 10-year old Account ⇒ many transactions Therefore, use snapshots: Periodically save snapshot of aggregate state Typically serialize a memento of the aggregate Load latest snapshot + subsequent events @crichardson

  35. Event Store API trait EventStore { def save[T <: Aggregate[T]](entity: T, events: Seq[Event], assignedId : Option[EntityId] = None): Future[EntityWithIdAndVersion[T]] def update[T <: Aggregate[T]](entityIdAndVersion : EntityIdAndVersion, entity: T, events: Seq[Event]): Future[EntityWithIdAndVersion[T]] def find[T <: Aggregate[T] : ClassTag](entityId: EntityId) : Future[EntityWithIdAndVersion[T]] def findOptional[T <: Aggregate[T] : ClassTag](entityId: EntityId) Future[Option[EntityWithIdAndVersion[T]]] def subscribe(subscriptionId: SubscriptionId): Future[AcknowledgableEventStream] } @crichardson

  36. Event store implementations Home-grown/DIY geteventstore.com by Greg Young Talk to me about my project :-) @crichardson

  37. Business benefits of event sourcing Built-in, reliable audit log Enables temporal queries Publishes events needed by big data/predictive analytics etc. Preserved history ⇒ More easily implement future requirements @crichardson

  38. Technical benefits of event sourcing Solves data consistency issues in a Microservice/NoSQL- based architecture: Atomically save and publish events Event subscribers update other aggregates ensuring eventual consistency Event subscribers update materialized views in SQL and NoSQL databases (more on that later) Eliminates O/R mapping problem @crichardson

  39. Drawbacks of event sourcing Weird and unfamiliar Events = a historical record of your bad design decisions Handling duplicate events can be tricky Application must handle eventually consistent data Event store only directly supports PK-based lookup (more on that later) @crichardson

  40. Agenda Why build event-driven microservices? Overview of event sourcing Designing microservices with event sourcing Implementing queries in an event sourced application Building and deploying microservices @crichardson

Recommend


More recommend