Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Events on the outside, on the inside and at the core (jaxlondon)


Published on

This presentation looks at the importance of events and the role that they play in software applications. We describe how events are a key application integration mechanism and how they are used by applications to communicate with the outside world. You will learn how the microservices inside a system can use events to maintain data consistency. We discuss how easy it is to implement both these mechanisms by developing your core business logic using an event-centric approach.

Published in: Software
  • Be the first to comment

Events on the outside, on the inside and at the core (jaxlondon)

  1. 1. @crichardson Events on the outside, on the inside and at the core Chris Richardson Founder of the original Author of POJOs in Action @crichardson
  2. 2. @crichardson Presentation goal How event sourcing enables the event-driven enterprise
  3. 3. @crichardson About Chris
  4. 4. @crichardson About Chris Consultant and trainer focusing on microservices (
  5. 5. @crichardson About Chris Founder of a startup that is creating a platform that makes it easy for application developers write microservices (
  6. 6. @crichardson For more information
  7. 7. @crichardson Agenda Events on the outside Events on the inside Events at the core with event sourcing Designing event-centric domain model
  8. 8. @crichardson What’s an event?
  9. 9. @crichardson Examples of events
  10. 10. @crichardson Instacart: event- driven grocery shopping
  11. 11. Who wants to be notified? Humans via Email SMS Mobile push … Applications Applications that implement other parts of the business process, e.g. order fulfillment system Analytics dashboards, monitoring, … Applications that deliver notifications to humans: Twilio, SendGrid, … …
  12. 12. @crichardson How: Polling for events HTTP Periodically poll for events AtomPub Based on HTTP Head is constantly changing Tail is immutable and can be efficiently cached High-latency, inefficient
  13. 13. @crichardson Using WebSockets Browser Web Socket STOMP Client application Service Web Socket STOMP Application SUBSCRIBE MESSAGE MESSAGE Low latency, more efficient, but what about past events?
  14. 14. @crichardson Webhooks = user-defined HTTP callback Client Service register(events, callbackUrl) POST callbackUrl POST callbackUrl … Low latency, more efficient, but what about past events?
  15. 15. @crichardson Github webhooks Installed on an organization or repository e.g. POST /repos/:owner/:repo/hooks Available events: push - push to a repository fork - repository is forked pull_request - assigned, unassigned, … push - push to a repository …
  16. 16. Twilio - Telephony and SMS as a service REST API Allocate phone numbers Make and receive phone calls Send and receive SMS messages Pay per use: Phone calls - per-minute SMS – per SMS sent or received Phone number – per month Examples OpenVBX is a web-based, open source phone system StubHub – notifies sellers of a pending sale via phone SurveyMonkey – interactive polling Salesforce – SMS-based voting for 19,000 conference attendees
  17. 17. @crichardson Using Twilio Twilio Your Application TwiML doc HTTP GET/ POST REST API Manage resources Send SMS Initiate voice calls Webhooks handle incoming SMS and voice calls Voice SMS Phone number SMS URL +VOICE URL
  18. 18. @crichardson Integration hubs - Zapier, IFTTT Application abstraction: Triggers - events published by application: polling or Webhooks Action - operation supported by application, e.g. REST API end points
  19. 19. @crichardson WebHooks = web friendly publish/subscribe
  20. 20. @crichardson Enterprise integration patterns
  21. 21. @crichardson messaging system Messaging-based IPC Sender RecipientChannel message
  22. 22. @crichardson Example messaging systems
  23. 23. @crichardson The event-driven enterprise App A App BApp X App Y Firewall Message Broker webhooks WebSockets AtomPub App Z App C Msg Broker Client Msg Broker Client Msg Broker Client App D Msg Broker Client Inside the firewallOutside the firewall
  24. 24. @crichardson Agenda Events on the outside Events on the inside Events at the core with event sourcing Designing event-centric domain model
  25. 25. @crichardson Traditional monolithic architecture Simple to develop test deploy scale Shopping Cart Customers Orders Mobile client REST API Browser Web UI Message Broker Adapter MySQL Adapter RDBMS … Message Broker
  26. 26. @crichardson But that leads* to monolithic hell For large and/or complex applications…
  27. 27. @crichardson Today: use a microservice, polyglot architecture Orders Customers … Shopping UI Mobile Client Browser API Gateway Order management REST API Customer Management REST API …. REST API Order Database (MongoDB) MongoDB Adapter Customer Database (Sharded MySQL) MySQL Adapter
  28. 28. @crichardson But now we have distributed data management problems
  29. 29. @crichardson Example: placing an order Order Service Customer Service Order Database Customer Database Order #1 Customer #1 No 2PC No ACID NoSQL SQL
  30. 30. @crichardson Customer management How to maintain invariants? Order management Order Service placeOrder() Customer Service updateCreditLimit() Customer creditLimit ... has ordersbelongs toOrder total Invariant: sum(open <= customer.creditLimit ?
  31. 31. @crichardson Use an event-driven architecture Services publish events when something important happens, e.g. state changes Services subscribe to events and update their state Maintain eventual consistency across multiple aggregates (in multiple datastores) Synchronize replicated data
  32. 32. @crichardson Event-driven application architecture Application Service A Service B Message Broker Service C Msg Broker Client Msg Broker Client Msg Broker Client Service D Msg Broker Client
  33. 33. @crichardson Order Management Order id : 4567 total: 343 state = CREATED Customer Management Customer creditLimit : 12000 creditReservations: {} Customer creditLimit : 12000 creditReservations: { 4567 -> 343} Order id : 4567 total: 343 state = OPEN Eventually consistent credit checking Message Bus createOrder() Publishes: Subscribes to: Subscribes to: publishes: OrderCreatedEvent CreditReservedEvent OrderCreatedEvent CreditReservedEvent
  34. 34. @crichardson Now there are two problems to solve….
  35. 35. @crichardson Problem #1: How to design eventually consistent business logic? More on that later….
  36. 36. @crichardson Problem #2: How to atomically update database and publish an event Order Service Order Database Message Broker insert Order publish OrderCreatedEvent dual write problem ?
  37. 37. @crichardson Update and publish using 2PC Guaranteed atomicity BUT Need a distributed transaction manager Database and message broker must support 2PC Impacts reliability Not fashionable 2PC is best avoided
  38. 38. @crichardson Transaction log tailing How: Read the database “transaction log” = single source of truth Publish events to message broker LinkedIn databus Supports Oracle and MySQL Publish as events AWS DynamoDB streams Ordered sequence of creates, updates, deletes made to a DynamoDB table Last 24 hours Subscribe to get changes MongoDB Read the oplog
  39. 39. Transaction log tailing: benefits and drawbacks Benefits No 2PC No application changes required Guaranteed to be accurate Drawbacks Immature Database specific solutions Low-level DB changes rather business level events = need to reverse engineer domain events
  40. 40. @crichardson Use database triggers Track changes to tables Insert events into an event table Use datastore as a message queue Pull events from event table and write to message broker
  41. 41. Database triggers: benefits and drawbacks Benefits No 2PC No application changes required
 Drawbacks Requires the database to support them Database specific solutions Low-level DB changes rather business level events = need to reverse engineer domain events Error-prone, e.g. missing trigger
  42. 42. @crichardson Application created events Use datastore as a message queue Txn #1: Update database: new entity state & event Txn #2: Consume event Txn #3: Mark event as consumed Eventually consistent mechanism (used by eBay) See BASE: An Acid Alternative,
  43. 43. Application created events Benefits High-level domain events No 2PC Drawbacks Requires changes to the application Only works for SQL and some NoSQL databases Error-prone
  44. 44. @crichardson Agenda Events on the outside Events on the inside Events at the core with event sourcing Designing event-centric domain model
  45. 45. @crichardson Just publish events Application Database Message Broker update publish X
  46. 46. @crichardson Event sourcing For each aggregate (business entity): Identify (state-changing) domain events Define Event classes For example, ShoppingCart: ItemAddedEvent, ItemRemovedEvent, OrderPlacedEvent Order: OrderCreated, OrderCancelled, OrderApproved, OrderRejected, OrderShipped
  47. 47. @crichardson Persists events NOT current state Order status …. Event table 101 ACCEPTED Order table X OrderCreated101 901 … OrderApproved101 902 … OrderShipped101 903 …
  48. 48. @crichardson Replay events to recreate state Order state OrderCreated(…) OrderAccepted(…) OrderShipped(…) Events Periodically snapshot to avoid loading all events
  49. 49. @crichardson The present is a fold over history currentState = foldl(applyEvent, initialState, events)
  50. 50. @crichardson Domain logic = event-driven aggregates Customer AggregateOrder Aggregate Order Created Event Check Credit Command Credit Reserved Event Approve Order Command Create Order Command External request Emits events Event Command
  51. 51. @crichardson Request handling in an event-sourced application HTTP Handler Event Store pastEvents = findEvents(entityId) Order new() applyEvents(pastEvents) newEvents = processCmd(SomeCmd) saveEvents(newEvents) Microservice A (optimistic locking)
  52. 52. @crichardson Event Store publishes events - consumed by other services Event Store Event Subscriber subscribe(EventTypes) publish(event) publish(event) Aggregate CQRS View update() update() Microservice B send notifications …
  53. 53. Event store = database + message broker Hybrid database and message broker Implementations: Home-grown/DIY by Greg Young (mine) Event Store Save aggregate events Get aggregate events Subscribe to events
  54. 54. @crichardson Benefits of event sourcing Solves data consistency issues in a Microservice/NoSQL-based architecture Reliable event publishing: publishes events needed by predictive analytics etc, user notifications,… Eliminates O/R mapping problem (mostly) Reifies state changes: Built-in, reliable audit log, temporal queries Preserved history More easily implement future requirements
  55. 55. @crichardson 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 => use Command Query Responsibility Segregation (CQRS) to handle queries
  56. 56. @crichardson Agenda Events on the outside Events on the inside Events at the core with event sourcing Designing event-centric domain model
  57. 57. @crichardson Use the familiar building blocks of DDD Entity Value object Services Repositories Aggregates ⟸ essential
  58. 58. Aggregate design Graph consisting of a root entity and one or more other entities and value objects Each core business entity = Aggregate: e.g. customer, Account, Order, Product, …. Reference other aggregate roots via primary key Often contains partial copy of other aggregates’ data Order OrderLine Item quantity productId productName productPrice customerId Address street city …
  59. 59. @crichardson Partition the domain model into Aggregates Order OrderLine Item quantity … Address street city … Customer Product name price
  60. 60. @crichardson Transaction = processing one command by one aggregate No opportunity to update multiple aggregates within a transaction Aggregate granularity is important If an update must be atomic (i.e. no compensating transaction) then it must be handled by a single aggregate e.g. scanning boarding pass at security checkpoint or when entering jetway
  61. 61. @crichardson Aggregate granularity Consistency Scalability/ User experience Customer Order Product Customer Order Product Customer Order Product
  62. 62. Designing domain events Record state changes for an aggregate Part of the public API of the domain model ProductAddedToCart id : TimeUUID senderId: UUID productId productName productPrice … Required by aggregate Enrichment: Useful for consumers Event metadata
  63. 63. @crichardson Example event
  64. 64. @crichardson Designing commands Created by a service from incoming request Processed by an aggregate Immutable Contains value objects for Validating request Creating event Auditing user activity
  65. 65. @crichardson Example command
  66. 66. @crichardson Hybrid OO/FP domain objects
  67. 67. @crichardson OO = State + Behavior creditLimit creditReservations : Map[OrderId, Money] Customer List<Event> processCommand ( Command aCommand) { … } void applyEvent (Event anEvent) { … } State Behavior
  68. 68. @crichardson Aggregate traits Map Command to Events Apply event returning updated Aggregate Used by Event Store to reconstitute aggregate
  69. 69. @crichardson ReflectiveMutableCommand ProcessingAggregate
  70. 70. @crichardson Customer - command processing
  71. 71. @crichardson Customer - applying events
  72. 72. @crichardson Event Store API T is a subclass of Aggregate[T] Rx Observable = Future++
  73. 73. @crichardson Creating an order save() concisely specifies: 1.Creates Customer aggregate 2.Processes command 3.Applies events 4.Persists events
  74. 74. @crichardson Event handling in Customers 1.Load Customer aggregate 2.Processes command 3.Applies events 4.Persists events Triggers BeanPostProcessor Durable subscription name
  75. 75. @crichardson Summary Events are a central to modern applications Events integrate applications Events maintain data consistency in a microservices architecture Build events into the core of your application using event sourcing
  76. 76. @crichardson @crichardson Questions?