lagom - mircoservices "just right"
TRANSCRIPT
![Page 1: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/1.jpg)
Markus Jura@markusjura
Mircoservices “Just Right”
![Page 2: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/2.jpg)
Lagom - [lah-gome]
Adequate, sufficient, just right
![Page 3: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/3.jpg)
• Overview
• Developer experience
• Service API
• Persistence & Clustering
• Running in production
Agenda
![Page 4: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/4.jpg)
Overview
![Page 5: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/5.jpg)
• 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?
![Page 6: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/6.jpg)
• Java 8
• Play 2.5
• Akka 2.4 (Clustering, Streams, Persistence)
• Cassandra (default data store)
• Jackson (JSON serialization)
• Guice (DI)
Under the hood
![Page 7: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/7.jpg)
Developer experience
![Page 8: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/8.jpg)
Enough slides,
Demo time
![Page 9: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/9.jpg)
Service API
![Page 10: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/10.jpg)
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
![Page 11: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/11.jpg)
Service definition//thissourceisplacedinyourapiprojectpublicinterfaceFriendServiceextendsService{@OverridedefaultDescriptordescriptor(){returnnamed("friendservice").withCalls(namedCall("/api/users",this::createUser))}
ServiceCall<User,String>createUser();}
![Page 12: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/12.jpg)
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
![Page 13: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/13.jpg)
Strict MessagesdefaultDescriptordescriptor(){returnnamed("friendservice").withCalls(namedCall("/api/users",this::createUser))}
ServiceCall<User,String>createUser();
Strict messages are buffered into memory
![Page 14: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/14.jpg)
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)
![Page 15: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/15.jpg)
Remember the Service definition?//thissourceisplacedinyourapiprojectpublicinterfaceFriendServiceextendsService{@OverridedefaultDescriptordescriptor(){returnnamed("friendservice").withCalls(namedCall("/api/users",this::createUser))}
ServiceCall<User,String>createUser();}
![Page 16: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/16.jpg)
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"); }
![Page 17: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/17.jpg)
Intra-service communication
publicclassMyServiceImplimplementsMyService{privatefinalfriendService;
@InjectMyServiceImpl(FriendServicefriendService){this.friendService=friendService;}…
![Page 18: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/18.jpg)
Intra-service communication
@Override public ServiceCall<NotUsed, String> addFriend() { return request -> { CompletionStage<String> userId = friendService.createUser(user).invoke() return userId; } }
![Page 19: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/19.jpg)
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
![Page 20: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/20.jpg)
Persistence & Clustering
![Page 21: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/21.jpg)
Service owns its data
FriendService
Friend DB
ChirperService
Chirper DB
ActivityStreamService
![Page 22: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/22.jpg)
Lagom Persistence
Lagom Persistence
Event Sourcing
CQRSimplements leads to
![Page 23: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/23.jpg)
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
![Page 24: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/24.jpg)
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
![Page 25: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/25.jpg)
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
![Page 26: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/26.jpg)
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
![Page 27: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/27.jpg)
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
![Page 28: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/28.jpg)
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
![Page 29: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/29.jpg)
Event sourcing: Storing deltas
UserCreated (Alice)
Friend Added (Bob)
Friend Added (Peter)
Friend Removed(Bob)
![Page 30: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/30.jpg)
Traditional way
User(Alice)
Friend (Peter)
Friend (Bob)
![Page 31: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/31.jpg)
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
![Page 32: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/32.jpg)
Persistent Entity
DataStore(e.g.CassandraCluster)
FriendService
YPeter
FriendService
XBobAlice FriendService
YXY
![Page 33: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/33.jpg)
Event Sourcing: Snapshots
1 2 100 101 102 103..
Snapshot
![Page 34: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/34.jpg)
• 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
![Page 35: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/35.jpg)
Read-Side
UserCreated(Alice)
FriendAdded(Bob)
FriendAdded(Peter)
Alice
Bob
Peter
Alice
Bob
X
Y
![Page 36: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/36.jpg)
Read-Side
UserCreated(Alice)
FriendAdded(Bob)
FriendAdded(Peter)
FOLLOWERSuserid followedby
BobAliceBobXBobYPeterAlice
![Page 37: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/37.jpg)
• 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
![Page 38: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/38.jpg)
ConsistencyFOLLOWERSuserid followedby
BobAliceBobXBobYPeterAlice
DataStore(e.g.CassandraCluster)
Alice1 - Persistent Entity
2 - Journal / Event Log
3 - Read Side
![Page 39: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/39.jpg)
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
![Page 40: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/40.jpg)
Consistency• Depending on implementation and
configuration
• Popular choice: Casssandra
• “Tunable consistency”
• Use of quorums ensures consistencyDataStore(e.g.CassandraCluster)
2 - Journal / Event Log
![Page 41: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/41.jpg)
Consistency• Will not be updated immediately, but
deferred
• Not much different from queries in interactive applicationsFOLLOWERS
userid followedby
BobAliceBobXBobYPeterAlice
3 - Read Side
![Page 42: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/42.jpg)
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
![Page 43: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/43.jpg)
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)
![Page 44: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/44.jpg)
Production
![Page 45: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/45.jpg)
• sbt-native packager produces several packages
• ZIP
• Docker
• RPM
• ConductR bundle
Packaging
![Page 46: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/46.jpg)
• Infrastructure need to support Akka clustering
• Deployment tool
• Need to implement Lagom service locator interface
• Should handle node failure scenarios
Production considerations
![Page 47: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/47.jpg)
• Akka Cluster support
• Service locator
• Consolidated logging
• Restart services automatically
• Handling network failures
• Rolling updates
• Monitoring support
ConductR
![Page 48: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/48.jpg)
ConductR Demo
![Page 49: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/49.jpg)
• Maven support
• Message broker integration
• Scala API
• Support for other orchestration tools
• Support for writing integrations tests
• Swagger integration
Next steps
![Page 50: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/50.jpg)
• 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
![Page 51: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/51.jpg)
Read this book
https://www.lightbend.com/reactive-microservices-architecture
(free, registration required)
![Page 52: Lagom - Mircoservices "Just Right"](https://reader031.vdocuments.us/reader031/viewer/2022021919/587701a91a28ab890e8b4851/html5/thumbnails/52.jpg)