Top Banner
EVENT‐DRIVEN‐ ARCHITECTURE ON AWS USING AKKA
54

Event Sourcing using Akka on AWS

Apr 11, 2017

Download

Software

Daniel Pfeiffer
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Event Sourcing using Akka on AWS

EVENT‐DRIVEN‐ARCHITECTURE ONAWS USING AKKA

Page 2: Event Sourcing using Akka on AWS

Software Engineer @firstbird

Contact me: @pfeiffer_d_

DANIEL PFEIFFER

Page 3: Event Sourcing using Akka on AWS

THE JOURNEY OF EVENTSthat are stored with Akka Persistenceto be then distributed via AWSto be consumed with Akka Streamwhat comes after that

Page 4: Event Sourcing using Akka on AWS

THE EXAMPLE

Page 5: Event Sourcing using Akka on AWS

DOMAIN DRIVEN DESIGNWe are talking about Aggregates and Events

Page 6: Event Sourcing using Akka on AWS

EVENT SOURCING"Capture all changes to an application

state as a sequence of events" -Martin Fowler, 2005

Page 7: Event Sourcing using Akka on AWS

CQRS"Asking a question should not changethe answer." - Bertrand Meyer, 2012

Page 8: Event Sourcing using Akka on AWS

THE DIFFERENCE

Page 9: Event Sourcing using Akka on AWS

PERSISTENTACTORclass TimeEntryAggregate(id: String) extends PersistentActor{ override def persistenceId: String = ??? override def receiveCommand: Receive = ??? override def receiveRecover: Receive = ???}

Page 10: Event Sourcing using Akka on AWS

A PersistentActor class represents one DDDaggregate.

class TimeEntryAggregate(id: String) extends PersistentActor{ ... override def persistenceId: String = s"time-entry-$id" ...}

Page 11: Event Sourcing using Akka on AWS

A PersistentActor receives commands andpersists events.

case class CreateTimeEntry( begin: DateTime, end: DateTime)

case class TimeEntryCreated( begin: DateTime, end: DateTime, sequenceNr: Long)

Page 12: Event Sourcing using Akka on AWS

A PersistentActor receives commands andpersists events.

class TimeEntryAggregate(id: String) extends PersistentActor{ ... override def receiveCommand: Receive = case CreateTimeEntry(start, end) => val event = TimeEntryCreated(start,end, lastSequenceNr + 1) persist(event){e => // update internal state // here we go after the event is persisted } } ...}

Page 13: Event Sourcing using Akka on AWS

A PersistentActor recovers from the journalclass TimeEntryAggregate(id: String) extends PersistentActor{ ... override def receiveRecover: Receive = { case TimeEntryCreated(start,end) => // update internal state } ...}

Page 14: Event Sourcing using Akka on AWS

STORING EVENTS TO A JOURNALIS NICE, BUT ...

others may be as well interested, so we have todistribute them.

Page 15: Event Sourcing using Akka on AWS

WITHIN ONE JVM WE COULD...use Akka EventStream to publish events ...

class TimeEntryActor() extends PersistentActor{ ... persist(event){e => context.system.eventStream.publish(e) } ...}

Page 16: Event Sourcing using Akka on AWS

... and subscribe from interested actorsclass EventConsumer extends Actor{ override def preStart: Unit = { context.system.eventStream.subscribe(classOf[TimeEntryActor.TimeEntryCreated } override def receive: Receive = { case e: TimeEntryCreated => //do something with that event }}

Page 17: Event Sourcing using Akka on AWS

HOW DO I INTERACT WITH MYAGGREGATES?

Page 18: Event Sourcing using Akka on AWS

DON'T CALL ME! CALL MYOFFICE!

Page 19: Event Sourcing using Akka on AWS

EXAMPLE 1

Page 20: Event Sourcing using Akka on AWS

BUT WE WANT TO BE COOL

Page 21: Event Sourcing using Akka on AWS

DISTRIBUTED SYSTEMS AREHARD

Page 22: Event Sourcing using Akka on AWS

WE WANT TO MAKE THEMEASIER

Page 23: Event Sourcing using Akka on AWS

INTRODUCE A MESSAGEBROKER, PUB/SUB ...

Page 24: Event Sourcing using Akka on AWS

THE EXAMPLE ONAWS STEROIDS

Page 25: Event Sourcing using Akka on AWS
Page 26: Event Sourcing using Akka on AWS

TIME ENTRY SERVICE

Page 27: Event Sourcing using Akka on AWS

EMAIL SERVICE

Page 28: Event Sourcing using Akka on AWS

SQS FLOWSqsSource(...) .map(msg => Envelope(msg.receiptHandle, msg.body)) .via(unmarshal()) .via(process()) .runWith(ack(...))

Page 29: Event Sourcing using Akka on AWS

SQS MESSAGE{ "messageId" : "", "receiptHandle" : "", "md5OfBody" : "", "body" : ""}

Page 30: Event Sourcing using Akka on AWS

SNS NOTIFICATION ENVELOPE{ "Type" : "Notification", "MessageId" : "", "TopicArn" : "", "Subject" : "time_entry.approved", "Message" : "", "Timestamp" : "", "SignatureVersion" : "", "Signature" : "", "SigningCertURL" : "", "UnsubscribeURL" : ""}

Page 31: Event Sourcing using Akka on AWS

CHALLENGES

Page 32: Event Sourcing using Akka on AWS

EVENT SCHEMA EVOLUTIONadding a field to an event type,remove or rename field in event type,remove event type,split event into multiple smaller events.

Page 33: Event Sourcing using Akka on AWS

case class TimeEntryCreated( id: UUID, begin: DateTime, end: DateTime, timeEntryUserId: UUID, userId: UUID)

gets marshalled to{ "id" : "123456", "begin" : "2016-09-01 12:00:00", "end" : "2016-09-01 12:15:00", "timeEntryUserId" : "00000000-0000-0000-0000-000000000000", "userId" : "00000000-0000-0000-0000-000000000000"}

Page 34: Event Sourcing using Akka on AWS

Then something within our schema changescase class TimeEntryCreated( ... description: String ...)

and we will have fun with that one{ "id" : "123456", "begin" : "2016-09-01 12:00:00", "end" : "2016-09-01 12:15:00", "timeEntryUserId" : "00000000-0000-0000-0000-000000000000", "userId" : "00000000-0000-0000-0000-000000000000"}

Page 35: Event Sourcing using Akka on AWS

{ "id" : "123456", "begin" : "2016-09-01 12:00:00", "end" : "2016-09-01 12:15:00", "timeEntryUserId" : "00000000-0000-0000-0000-000000000000", "userId" : "00000000-0000-0000-0000-000000000000"}

needs to be transformed to that{ "id" : "123456", "begin" : "2016-09-01 12:00:00", "end" : "2016-09-01 12:15:00", "timeEntryUserId" : "00000000-0000-0000-0000-000000000000", "userId" : "00000000-0000-0000-0000-000000000000", "description" : "N/A"}

Page 36: Event Sourcing using Akka on AWS

class Evolution(system: ExtendedActorSystem) extends EventAdapter{} override def fromJournal(event: Any, manifest: String): EventSeq = { val es = ... //doing evolution on event EventSeq(es) } override def manifest(event: Any): String = { val version = ??? event.getClass.getSimpleName + ":" + version } override def toJournal(event: Any): Any = ??? //write to the journal}

Page 37: Event Sourcing using Akka on AWS

SCALING WITH AKKA CLUSTERON AWS

or "Who am I, and where are all the others?"

Page 38: Event Sourcing using Akka on AWS

JOINING A CLUSTER

gives you information about your instancehttp://169.254.169.254/latest/meta-data/instance-id

Page 39: Event Sourcing using Akka on AWS

PRESERVING MESSAGE ORDER

Page 40: Event Sourcing using Akka on AWS

The query side could look like that| id | ... | version || --- | --- | ------- || 1 | ... | 45 || 2 | ... | 3 || 3 | ... | 58 |

Page 41: Event Sourcing using Akka on AWS

CHOOSING THE RIGHTDATASTORE

you will make mistakes so plan for it

Page 42: Event Sourcing using Akka on AWS

ASYNCHRONOUS MEANS NOTIMMEDIATE

Page 43: Event Sourcing using Akka on AWS

WHY DO WE REALLY WANT TODO THAT?

Page 44: Event Sourcing using Akka on AWS

WE WANT TO SLEEP BETTER

Page 45: Event Sourcing using Akka on AWS

WE WANT TO GET RID OF OURMONOLITH

Page 46: Event Sourcing using Akka on AWS

OUR DEVELOPMENT PROCESS BENEFITS

Page 47: Event Sourcing using Akka on AWS

WE CAN ALWAYS AGGREGATE OUREVENTS

Page 48: Event Sourcing using Akka on AWS

IF SOMEONE STARTS TO ASKQUESTIONS...

An audit log is included in your application for free!

Page 49: Event Sourcing using Akka on AWS

SUMMARY

Page 50: Event Sourcing using Akka on AWS

THE FIRST PROTOTYPE IS EASY BUT TOTACKLE THE CHALLENGES NEEDS

EFFORT!

Page 51: Event Sourcing using Akka on AWS

CONFIGURE YOUR SQS QUEUESPROPERLY

Page 52: Event Sourcing using Akka on AWS

LET EACH SERVICE MANAGE IT'SRESOURCES ITSELF.

Page 53: Event Sourcing using Akka on AWS

ONE TOPIC PER AGGREGATE

Page 54: Event Sourcing using Akka on AWS

LITERATURE

https://www.infoq.com/articles/AmazonPubSubhttp://martinfowler.com/eaaDev/EventCollaboration.html

http://martinfowler.com/bliki/CQRS.htmlhttps://github.com/dpfeiffer/event-sourcing-aws-

akka-showcasehttp://www.oreilly.com/programming/free/reactive-

microservices-architecture.htmlhttp://doc.akka.io/docs/akka/snapshot/scala/persistence-

schema-evolution.html#persistence-schema-evolution-scala http://chrisloy.net/2014/05/11/akka-

cluster-ec2-autoscaling.html