lagom - mircoservices "just right"

Post on 12-Jan-2017

144 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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)

top related