Date post: | 16-Apr-2017 |
Category: |
Software |
Upload: | chris-richardson |
View: | 1,715 times |
Download: | 1 times |
@crichardson
Microservices in Java and Scala
Chris Richardson
Founder of Eventuate.io Founder of the original CloudFoundry.com Author of POJOs in Action
@crichardson [email protected] http://microservices.io http://eventuate.io http://plainoldobjects.com
Copyright © 2015. Chris Richardson Consulting, Inc. All rights reserved
@crichardson
About Chris
@crichardson
About Chris
Consultant and trainer focusing on
microservices (public class: April 28th, Oakland, CA)
http://www.chrisrichardson.net/
@crichardson
About Chris
Founder of a startup that is creating a platform that makes it easy for
application developers write microservices
(http://eventuate.io)
@crichardson
For more information
http://bit.ly/eventsmarch17
AgendaWhy a pattern language for microservices?
Monolith architecture vs. microservices
Developing microservices with event sourcing and CQRS
Microservices in Java
Microservices in Scala Example: real-time, collaborative Kanban board application
@crichardson
In 1986…
http://en.wikipedia.org/wiki/Fred_Brooks
@crichardson
Yet 30 years later….
If you __________________ a puppy will die Therefore you must _______________
@crichardson
Quiz - fill in the blanks….
mutate state
use monads
use objects
use functions
block a thread
use async.
make a REST call
send a messageuse Spring
use ….
@crichardson
How we make decisions
Decide using
emotions
Rationalize with our intellect
http://en.wikipedia.org/wiki/Mahout
@crichardson
The structure of a pattern
=
Great framework for discussing and thinking about technology
@crichardson
The structure of a pattern
Resulting context
aka the situation
Name
Context
Problem
Related patterns
(conflicting) issues etc to address Forces
Solution
@crichardson
AgendaWhy a pattern language for microservices?
Monolith architecture vs. microservices
Developing microservices with event sourcing and CQRS
Microservices in Java
Microservices in Scala Example: real-time, collaborative Kanban board application
@crichardson
In theory:
We can build a modular monolith
But in practice:
We build a big ball of mud
Microservices are not a silver bullet but …
@crichardson
The benefits typically outweigh the drawbacks
for large, complex applications
@crichardson
Build and deliver better software faster
@crichardson
Easily try other technologies
... and fail safely
AgendaWhy a pattern language for microservices?
Monolith architecture vs. microservices
Developing microservices with event sourcing and CQRS
Microservices in Java
Microservices in Scala Example: real-time, collaborative Kanban board application
Data management patterns
Database per Service
Event-driven architecture
Shared database
Event sourcing
Transaction log tailing
Database triggers
Application events
CQRS
Database architecture
Database per Service
Orders Service Customer Service
Order Database
Customer Database
Sharded SQL
NoSQL DB
@crichardson
Customer management
How to maintain invariants?
Order management
Order Service
placeOrder()
Customer Service
updateCreditLimit()
Customer
creditLimit ...
has ordersbelongs toOrder
total
Invariant: sum(open order.total) <= customer.creditLimit
?
@crichardson
Event-driven architecture
@crichardson
How atomically update database and publish an event
Order Service
Order Database
Message Broker
insert Order
publish OrderCreatedEvent
dual write problem
?
@crichardson
Reliably generating events
@crichardson
Use event-sourcingEvent table
Aggregate type
Event id
Aggregate id
Event data
Order 902101 …OrderApproved
Order 903101 …OrderShipped
Event type
Order 901101 …OrderCreated
@crichardson
Replay events to recreate state
Order
state
OrderCreated(…) OrderAccepted(…) OrderShipped(…)
Events
Periodically snapshot to avoid loading all events
But what about queries?
@crichardson
Command Query Responsibility Segregation (CQRS)
Command side
Commands
Aggregate
Event Store
Events
Query side
Queries
(Materialized) View
Events
@crichardson
Query-side design
Event Store
Updater
View Updater Service
Events
Reader
HTTP GET Request
View Query Service
View Store
e.g. MongoDB
Neo4J CloudSearch
update query
Eventuate architecture
Eventuate platform
Multiple flavors of client frameworks
“Traditional Java” mutable object-oriented domain objects
https://github.com/cer/event-sourcing-examples/tree/master/java-spring
Functional Scala with immutable domain objects
https://github.com/cer/event-sourcing-using-scala-typeclasses
Hybrid OO/Functional Scala with immutable domain objects
https://github.com/cer/event-sourcing-examples/tree/master/scala-spring
AgendaWhy a pattern language for microservices?
Monolith architecture vs. microservices
Developing microservices with event sourcing and CQRS
Microservices in Java
Microservices in Scala Example: real-time, collaborative Kanban board application
Customer command side
@crichardson
The Customer aggregate
creditLimit creditReservations : Map<OrderId, Money>
Customer
List<Event> process(CreateCustomerCommand cmd) { … } List<Event> process(ReserveCreditCommand cmd) { … } … void apply(CustomerCreatedEvent anEvent) { … } void apply(CreditServedEvent anEvent) { … } …
State
Behavior
@crichardson
Familiar concepts restructured
class Customer {
public void reserveCredit( orderId : String, amount : Money) {
// verify
// update state this.xyz = … }
public List<Event> process( ReserveCreditCommand cmd) { // verify … return … new CreditReservedEvent(); }
public void apply( CreditReservedEvent event) { // update state this.xyz = event.xyz }
@crichardson
Customer command processing
@crichardson
Customer applying events
@crichardson
Creating an order
save() concisely specifies: 1.Creates Order aggregate 2.Processes command 3.Applies events 4.Persists events
@crichardson
Event handling in Customers
1. Load Customer aggregate 2. Processes command 3. Applies events 4. Persists events
Triggers BeanPostProcessor Durable subscription name
Customer - query side
@crichardson
MongoDB view: customer and their order history
{ "_id" : "0000014f9a45004b 0a00270000000000", "_class" : "net.chrisrichardson…..views.orderhistory.CustomerView", "version" : NumberLong(5), "orders" : { "0000014f9a450063 0a00270000000000" : { "state" : "APPROVED", "orderId" : "0000014f9a450063 0a00270000000000", "orderTotal" : { "amount" : "1234" } }, "0000014f9a450063 0a00270000000001" : { "state" : "REJECTED", "orderId" : "0000014f9a450063 0a00270000000001", "orderTotal" : { "amount" : "3000" } } }, "name" : "Fred", "creditLimit" : { "amount" : "2000" } }
Denormalized = efficient lookup
@crichardson
Query-side event handler that updates customer view
@crichardson
Updating and query view using Spring Data for MongoDB...
AgendaWhy a pattern language for microservices?
Monolith architecture vs. microservices
Developing microservices with event sourcing and CQRS
Microservices in Java
Microservices in Scala Example: real-time, collaborative Kanban board application
@crichardson
Functional Customer aggregate
Customer
creditLimit creditReservations …
CustomerAggregate
processCommand(Account, Command) : Seq[Events]
applyEvent(Account, Event) : Account
Immutable state Behavior
@crichardson
Aggregate type classesUsed by
Event Store to
reconstitute aggregates
Hardwired
@crichardson
Customer Aggregate….State
Behavior
@crichardson
…command processing…
@crichardson
… applying events
AgendaWhy a pattern language for microservices?
Monolith architecture vs. microservices
Developing microservices with event sourcing and CQRS
Microservices in Java
Microservices in Scala Example: real-time, collaborative Kanban board application
@crichardson
Kanban board example
@crichardson
ArchitectureCreate/update boards
and tasks
Change notifications Materialized views
Event Store
@crichardson
Demo
Summary
Microservices are not a silver bullet but they are the best choice for large/complex applications
Use an event-driven microservices architecture
Build services using event sourcing + CQRS
Using a language/framework specific programming model