Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich...
-
Upload
chris-richardson -
Category
Software
-
view
1.481 -
download
1
Transcript of Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich...
![Page 1: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/1.jpg)
@crichardson
Building and deploying microservices with event
sourcing, CQRS and DockerChris Richardson
Author of POJOs in Action Founder of the original CloudFoundry.com
@crichardson [email protected] http://plainoldobjects.com http://microservices.io
![Page 2: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/2.jpg)
@crichardson
Presentation goal
Share my experiences with building and deploying an application using Scala, functional domain models, microservices, event sourcing,
CQRS, and Docker
![Page 3: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/3.jpg)
@crichardson
About Chris
![Page 4: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/4.jpg)
@crichardson
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
![Page 5: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/5.jpg)
@crichardson
For more information
https://github.com/cer/event-sourcing-examples
http://microservices.io
http://plainoldobjects.com/
https://twitter.com/crichardson
![Page 6: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/6.jpg)
@crichardson
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
![Page 7: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/7.jpg)
@crichardson
Tomcat
Traditional application architecture
Browser/Client
WAR/EAR
RDBMS
Customers
Accounts
Transfers
Banking
develop test
deploy
Simple
Load balancer
scale
Spring MVC
Spring Hibernate
...
HTML
REST/JSON
ACID
![Page 8: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/8.jpg)
@crichardson
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
![Page 9: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/9.jpg)
@crichardson
Apply the scale cube
X axis - horizontal duplication
Z axis
- data
partit
ioning
Y axis - functional
decomposition
Scale b
y split
ting s
imilar
thing
s
Scale by splitting
different things
![Page 10: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/10.jpg)
@crichardson
Use a microservice architecture
Banking UI
Account Management Service
MoneyTransfer Management Service
Account Database
MoneyTransfer Database
Standalone services
![Page 11: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/11.jpg)
@crichardson
Limitations of a single relational database
Scalability
Distribution
Schema updates
O/R impedance mismatch
Handling semi-structured data
![Page 12: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/12.jpg)
@crichardson
Use a sharded relational database
![Page 13: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/13.jpg)
@crichardson
Use NoSQL databases
Avoids the limitations of RDBMS
For example,
text search ⇒ Solr/Cloud Search
social (graph) data ⇒ Neo4J
highly distributed/available database ⇒ Cassandra
...
![Page 14: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/14.jpg)
@crichardson
Different modules use different types of databases
IEEE Software Sept/October 2010 - Debasish Ghosh / Twitter @debasishg
![Page 15: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/15.jpg)
@crichardson
But this results in distributed data management problems
![Page 16: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/16.jpg)
@crichardson
Example #1 - SQL + Text Search engine
Application
MySQL ElasticSearch
How to maintain consistency without 2PC?
Product #1 Product #1
![Page 17: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/17.jpg)
@crichardson
Example #2 - Cassandra main table <=> index table
Application
Cassandra
How to maintain consistency without 2PC?
Main Table
Denormalized view
Index Table
![Page 18: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/18.jpg)
@crichardson
Example #3: Money transferAccount Management
ServiceMoneyTransfer
Management Service
Account Database
MoneyTransfer Database
Account #2
Account #1 Money Transfer
How to maintain consistency without 2PC?
![Page 19: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/19.jpg)
@crichardson
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
![Page 20: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/20.jpg)
@crichardson
Event-driven synchronization: SQL + Text Search engine
Catalog Service
MySQL ElasticSearch
Product #1 Product #1
Search Service
Message Bus
Insert Product Created
Product Created Index Doc
create product
![Page 21: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/21.jpg)
@crichardson
MoneyTransferServiceMoneyTransfer
fromAccountId = 101 toAccountId = 202 amount = 55 state = INITIAL
MoneyTransfer fromAccountId = 101 toAccountId = 202 amount = 55 state = DEBITED
MoneyTransfer fromAccountId = 101 toAccountId = 202 amount = 55 state = COMPLETED
Eventually consistent money transfer
Message Bus
AccountService
transferMoney()
Publishes:Subscribes to:
Subscribes to:
publishes:
MoneyTransferCreatedEvent
AccountDebitedEvent
DebitRecordedEvent
AccountCreditedEventMoneyTransferCreatedEvent
DebitRecordedEvent
AccountDebitedEventAccountCreditedEvent
Account id = 101 balance = 250
Account id = 202 balance = 125
Account id = 101 balance = 195
Account id = 202 balance = 180
![Page 22: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/22.jpg)
@crichardson
To maintain consistency a service must
atomically publish an event whenever
a domain object changes
![Page 23: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/23.jpg)
How to atomically update the datastore and publish event(s)?
Use 2PC
Guaranteed atomicity BUT
Need a distributed transaction manager
Database and message broker must support 2PC
Impacts reliability
Not fashionable
2PC is best avoided
Use datastore as a message queue
1. Update database: new entity state & event
2. Consume event & mark event as consumed
Eventually consistent mechanism
See BASE: An Acid Alternative, http://bit.ly/ebaybase
• BUT Tangled business logic and event publishing code
• Difficult to implement when using a NoSQL database :-(
![Page 24: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/24.jpg)
@crichardson
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
![Page 25: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/25.jpg)
@crichardson
Event sourcingFor each aggregate:
Identify (state-changing) domain events
Define Event classes
For example,
Account: AccountOpenedEvent, AccountDebitedEvent, AccountCreditedEvent
ShoppingCart: ItemAddedEvent, ItemRemovedEvent, OrderPlacedEvent
![Page 26: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/26.jpg)
@crichardson
Persists events NOT current state
Account
balance
open(initial) debit(amount) credit(amount)
AccountOpened
Event table
AccountCredited
AccountDebited
101 450
Account tableX101
101
101
901
902
903
500
250
300
![Page 27: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/27.jpg)
@crichardson
Replay events to recreate state
Account
balance
AccountOpenedEvent(balance) AccountDebitedEvent(amount) AccountCreditedEvent(amount)
Events
![Page 28: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/28.jpg)
@crichardson
Before: update state + publish events
Two actions that must be atomic
Single action that can be done atomically
Now: persist (and publish) events
![Page 29: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/29.jpg)
@crichardson
Aggregate traits
Map Command to Events
Apply event returning updated Aggregate
![Page 30: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/30.jpg)
@crichardson
Account - command processing
Prevent overdraft
![Page 31: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/31.jpg)
@crichardson
Account - applying eventsImmutable
![Page 32: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/32.jpg)
@crichardson
Request handling in an event-sourced application
HTTP Handler
Event Store
pastEvents = findEvents(entityId)
Account
new()
applyEvents(pastEvents)
newEvents = processCmd(SomeCmd)
saveEvents(newEvents)
Microservice A
![Page 33: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/33.jpg)
@crichardson
Event Store publishes events - consumed by other services
Event Store
Event Subscriber
subscribe(EventTypes)
publish(event)
publish(event)
Aggregate
NoSQL materialized
view
update()
update()
Microservice B
![Page 34: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/34.jpg)
@crichardson
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
![Page 35: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/35.jpg)
@crichardson
Event Store APItrait 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] }
![Page 36: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/36.jpg)
@crichardson
Event store implementations
Home-grown/DIY
geteventstore.com by Greg Young
Talk to me about my project :-)
![Page 37: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/37.jpg)
@crichardson
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
![Page 38: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/38.jpg)
@crichardson
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
![Page 39: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/39.jpg)
@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 (more on that later)
![Page 40: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/40.jpg)
@crichardson
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
![Page 41: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/41.jpg)
@crichardson
The anatomy of a microservice
Event Store
HTTP Request
HTTP Adapter
Aggregate
Event Adapter
Cmd
Cmd
EventsEvents
Xyz Adapter
Xyz Request
microservice
![Page 42: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/42.jpg)
@crichardson
Asynchronous Spring MVC controller
![Page 43: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/43.jpg)
@crichardson
MoneyTransferService
DSL concisely specifies: 1.Creates MoneyTransfer aggregate 2.Processes command 3.Applies events 4.Persists events
![Page 44: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/44.jpg)
@crichardson
MoneyTransfer Aggregate
![Page 45: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/45.jpg)
@crichardson
Handling events published by Accounts
1.Load MoneyTransfer aggregate 2.Processes command 3.Applies events 4.Persists events
![Page 46: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/46.jpg)
@crichardson
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
![Page 47: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/47.jpg)
@crichardson
Let’s imagine that you want to display an account and it’s recent transactions...
![Page 48: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/48.jpg)
@crichardson
Displaying balance + recent credits and debits
We need to do a “join: between the Account and the corresponding MoneyTransfers
(Assuming Debit/Credit events don’t include other account, ...)
BUT Event Store = primary key lookup of individual aggregates, ...
⇒ Use Command Query Responsibility Segregation
![Page 49: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/49.jpg)
@crichardson
Command Query Responsibility Segregation (CQRS)
Command-side
Commands
Aggregate
Event Store
Events
Query-side
Queries
(Denormalized) View
Events
![Page 50: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/50.jpg)
@crichardson
Query-side microservices
Event Store
Updater - microservice
View Updater Service
EventsReader - microservice
HTTP GET Request
View Query Service
View Store
e.g. MongoDB
Neo4J CloudSearch
update query
![Page 51: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/51.jpg)
@crichardson
Persisting account balance and recent transactions in MongoDB
{ id: "298993498", balance: 100000, transfers : [
{"transferId" : "4552840948484", "fromAccountId" : 298993498, "toAccountId" : 3483948934, "amount" : 5000}, ...
], changes: [ {"changeId" : "93843948934", "transferId" : "4552840948484", "transactionType" : "AccountDebited", "amount" : 5000}, ... ] }
Denormalized = efficient lookup
MoneyTransfers that update the account
The debits and credits
Current balance
![Page 52: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/52.jpg)
@crichardson
Persisting account info using MongoDB...
class AccountInfoUpdateService (accountInfoRepository : AccountInfoRepository, mongoTemplate : MongoTemplate) extends CompoundEventHandler {
@EventHandlerMethod def created(de: DispatchedEvent[AccountOpenedEvent]) = …
@EventHandlerMethod def recordDebit(de: DispatchedEvent[AccountDebitedEvent]) = …
@EventHandlerMethod def recordCredit(de: DispatchedEvent[AccountCreditedEvent]) = …
@EventHandlerMethod def recordTransfer(de: DispatchedEvent[MoneyTransferCreatedEvent]) = …
}
![Page 53: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/53.jpg)
Other kinds of viewsAWS Cloud Search
Text search as-a-Service
View updater batches aggregates to index
View query service does text search
AWS DynamoDB
NoSQL as-a-Service
On-demand scalable - specify desired read/write capacity
Document and key-value data models
Useful for denormalized, UI oriented views
![Page 54: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/54.jpg)
Benefits and drawbacks of CQRS
Benefits
Necessary in an event-sourced architecture
Separation of concerns = simpler command and query models
Supports multiple denormalized views
Improved scalability and performance
Drawbacks
Complexity
Potential code duplication
Replication lag/eventually consistent views
![Page 55: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/55.jpg)
@crichardson
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
![Page 56: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/56.jpg)
@crichardson
My application architecture
API gateway Event
Store
Service 1
Service 2
Service ...
Event Archiver
IndexerAWS Cloud Search
S3
NodeJS Scala/Spring Boot
![Page 57: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/57.jpg)
@crichardson
Spring Boot based micro services
Makes it easy to create stand-alone, production ready microservices
Automatically configures Spring using Convention over Configuration
Externalizes configuration
Built-in health checks and (Codahale) metrics
Generates standalone executable JARs with embedded web server
![Page 58: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/58.jpg)
@crichardson
Jenkins-based deployment pipeline
Build & Test microservice
Build & Test Docker image
Deploy Docker image
to registry
One pipeline per microservice
![Page 59: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/59.jpg)
@crichardson
Building Docker images
cp ../build/libs/service.${1}.jar build/service.jar
docker build -t service-${VERSION} .
docker/build.sh
Building only takes 5 seconds!
![Page 60: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/60.jpg)
@crichardson
Smoke testing docker images
Smoke test
Docker daemon
Service containerGET /health
POST /containers/create
creates
POST /containers/{id}/start
Docker daemon must listen on TCP port
![Page 61: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/61.jpg)
@crichardson
Publishing Docker images
docker tag service-${VERSION}:latest \ ${REGISTRY_HOST_AND_PORT}/service-${VERSION}
docker push ${REGISTRY_HOST_AND_PORT}/service-${VERSION}
docker/publish.sh
Pushing only takes 25 seconds!
![Page 62: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/62.jpg)
@crichardson
CI environment runs on Docker
EC2 Instance
Jenkins Container
Artifactory container
EBS volume
/jenkins-home
/gradle-home
/artifactory-home
![Page 63: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/63.jpg)
@crichardson
Updating the production environment
Large EC2 instance running Docker
Deployment tool:
1. Compares running containers with what’s been built by Jenkins
2. Pulls latest images from Docker registry
3. Stops old versions
4. Launches new versions
One day: use Docker clustering solution and a service discovery mechanism,
Most likely, AWS container service
Mesos and Marathon + Zookeeper, Kubernetes or ???
![Page 64: Building and deploying microservices with event sourcing, CQRS and Docker (Berlin microxchg, Munich microservices meetup)](https://reader036.fdocuments.net/reader036/viewer/2022082215/55a522f31a28abaf348b4871/html5/thumbnails/64.jpg)
@crichardson
Summary
Event sourcing solves key data consistency issues with:
Microservices
Partitioned SQL/NoSQL databases
Use CQRS to implement materialized views for queries
Spring Boot is a great foundation for microservices
Docker is a great way to package microservices