Download - Lagom - Mircoservices "Just Right"
Markus Jura@markusjura
Mircoservices “Just Right”
Lagom - [lah-gome]
Adequate, sufficient, just right
• Overview
• Developer experience
• Service API
• Persistence & Clustering
• Running in production
Agenda
Overview
• Reactive
• Built-in resiliency & failure handling patterns
• Developer experience
• No setup of external services
• Intra-service communication just works
• Services automatically reload on code change
• Takes you through to production deployment
Why Lagom?
• Java 8
• Play 2.5
• Akka 2.4 (Clustering, Streams, Persistence)
• Cassandra (default data store)
• Jackson (JSON serialization)
• Guice (DI)
Under the hood
Developer experience
Enough slides,
Demo time
Service API
Each service definition is split into two sbt projects: api & impl
Anatomy Lagom project
my-lagom-system→Projectroot└helloworld-api→helloworldapiproject └helloworld-impl→helloworldimplementationproject └project→sbtconfigurationfiles └plugins.sbt→sbtplugins└build.sbt→Yourprojectbuildfile
Service definition//thissourceisplacedinyourapiprojectpublicinterfaceFriendServiceextendsService{@OverridedefaultDescriptordescriptor(){returnnamed("friendservice").withCalls(namedCall("/api/users",this::createUser))}
ServiceCall<User,String>createUser();}
Service call explainedpublicinterfaceServiceCall<Request,Response>{CompletionStage<Response>invoke(Requestrequest)}
• ServiceCall is invoked when consuming a service
• JSON is the default serialization format for request/response messages
• There are two kinds of request/response messages
• Strict
• Streamed
Strict MessagesdefaultDescriptordescriptor(){returnnamed("friendservice").withCalls(namedCall("/api/users",this::createUser))}
ServiceCall<User,String>createUser();
Strict messages are buffered into memory
Streamed Messagesdefault Descriptor descriptor() { return named("activityservice").withCalls( pathCall("/activity/:userId", this::stream) ) }
ServiceCall<NotUsed, Source<Tweet, ?>> stream(String userId);
• Streamed message is of type Source (Akka streams API)
• Back-pressured, asynchronous handling of messages
• Lagom selects transport protocol (currently WebSockets)
Remember the Service definition?//thissourceisplacedinyourapiprojectpublicinterfaceFriendServiceextendsService{@OverridedefaultDescriptordescriptor(){returnnamed("friendservice").withCalls(namedCall("/api/users",this::createUser))}
ServiceCall<User,String>createUser();}
Service implementation
import com.lightbend.lagom.javadsl.api.*; import akka.NotUsed; import static java.util.concurrent.CompletableFuture.completedFuture;
@Override public ServiceCall<User, String> createUser() { return request -> completedFuture("Created user"); }
Intra-service communication
publicclassMyServiceImplimplementsMyService{privatefinalfriendService;
@InjectMyServiceImpl(FriendServicefriendService){this.friendService=friendService;}…
Intra-service communication
@Override public ServiceCall<NotUsed, String> addFriend() { return request -> { CompletionStage<String> userId = friendService.createUser(user).invoke() return userId; } }
Circuit breakers
• Circuit breaker is used to provide stability and prevent cascading failures
• Services calls interacting with Lagom services are using circuit breakers by default
• Circuit breakers can be configured
• Each service call can have a separate circuit breaker
Persistence & Clustering
Service owns its data
FriendService
Friend DB
ChirperService
Chirper DB
ActivityStreamService
Lagom Persistence
Lagom Persistence
Event Sourcing
CQRSimplements leads to
Persistent Entities
• Persistent Entity corresponds to an Aggregate Root (DDD)
• Persistent Entities receive commands
• Triggered by a command, Persistent Entities will change their state
• Example: Add friend, remove friend
FriendService
Peter
Bob
Alice
Lagom Cluster• Lagom allows you to scale
out by forming a cluster of nodes
• Nodes can be added and removed dynamically
Node ANode B
Node C
Node Djoin
Lagom Cluster• Lagom allows you to scale
out by distributing your Persistent Entities in the cluster
Node A Node B
Node C
XBobAlice
Z
XY
PaulPeter
Lagom Cluster• We have now moved from a
CRUD approach to a Memory Image approach
• We keep all* our data in memory!
• See http://martinfowler.com/bliki/MemoryImage.html
(*) or a working set, actors can be passivated and activated as needed
Node A Node B
Node C
XBobAlice
Z
XY
PaulPeter
Lagom Persistence• But how does our data
survive a system crash?
• We log all the state changes!
• Persistent Entities are recreated on another node and all state changes are replayed
Node A Node B
Node C
XBobAlice
Z
XY
PaulPeter
Event sourcing: Storing deltas
• Every state change is materialized in an Event • All events are stored in an Event Log • Current state is constructed by replaying all events
Event sourcing: Storing deltas
UserCreated (Alice)
Friend Added (Bob)
Friend Added (Peter)
Friend Removed(Bob)
Traditional way
User(Alice)
Friend (Peter)
Friend (Bob)
Event Sourcing: Benefits
• Bullet-proof auditing and historical tracing
• Support future ways of looking at data
• No object-relational impedance mismatch
• Performance and scalability
• Testability
Persistent Entity
DataStore(e.g.CassandraCluster)
FriendService
YPeter
FriendService
XBobAlice FriendService
YXY
Event Sourcing: Snapshots
1 2 100 101 102 103..
Snapshot
• Keep all data in memory
• Optional: Only working set, by using passivation/activation
• Store all state changes as events
• Replay all events to re-create the state
• Optional: Start from snapshot
• Scale out with Lagom Cluster and scalable data store
Event Sourcing with Lagom Persistence
Read-Side
UserCreated(Alice)
FriendAdded(Bob)
FriendAdded(Peter)
Alice
Bob
Peter
Alice
Bob
X
Y
Read-Side
UserCreated(Alice)
FriendAdded(Bob)
FriendAdded(Peter)
FOLLOWERSuserid followedby
BobAliceBobXBobYPeterAlice
• Derived from event log
• Can be discarded and re-created
• The “book of record” is the event log
• Can be scaled out by creating copies - it’s read only
Read-Side
ConsistencyFOLLOWERSuserid followedby
BobAliceBobXBobYPeterAlice
DataStore(e.g.CassandraCluster)
Alice1 - Persistent Entity
2 - Journal / Event Log
3 - Read Side
Consistency
Alice
• Persistent Entities define an Aggregate root
• Aggregate Root is the Transactional Boundary
• Strong consistency within an Aggregate Root
• Commands are executed sequentially on the latest state
• No limit to scalability
1 - Persistent Entity
Consistency• Depending on implementation and
configuration
• Popular choice: Casssandra
• “Tunable consistency”
• Use of quorums ensures consistencyDataStore(e.g.CassandraCluster)
2 - Journal / Event Log
Consistency• Will not be updated immediately, but
deferred
• Not much different from queries in interactive applicationsFOLLOWERS
userid followedby
BobAliceBobXBobYPeterAlice
3 - Read Side
Event Sourcing with Lagom Persistence revisited
• Keep all data in memory!
• Store all state changes as events
• Replay all events of a Persistent Entity to recreate it
• Strong consistency for Persistent Entity (aggregate) and Journal
• Eventual consistency for Read-Side
What if I don’t want to use Event Sourcing?
• Don’t use Lagom Persistence
• You can use any data store
• Beware of blocking APIs (JDBC)
Production
• sbt-native packager produces several packages
• ZIP
• Docker
• RPM
• ConductR bundle
Packaging
• Infrastructure need to support Akka clustering
• Deployment tool
• Need to implement Lagom service locator interface
• Should handle node failure scenarios
Production considerations
• Akka Cluster support
• Service locator
• Consolidated logging
• Restart services automatically
• Handling network failures
• Rolling updates
• Monitoring support
ConductR
ConductR Demo
• Maven support
• Message broker integration
• Scala API
• Support for other orchestration tools
• Support for writing integrations tests
• Swagger integration
Next steps
• Getting started: lightbend.com/lagom
• Examples: lightbend.com/activator/templates
• Contribute: https://github.com/lagom
• Communicate:
• https://groups.google.com/forum/#!forum/lagom-framework
• https://gitter.im/lagom/lagom
• Lightbend Proof of Concept Program: lightbend.com/company/contact
Try it out
Read this book
https://www.lightbend.com/reactive-microservices-architecture
(free, registration required)