Top Banner
We broke up with the Monolith, and started dating Event Sourcing Migrations, Event Sourcing, AWS, and other Demeter things @JavierCane #symfonyCat - Symfony Catalunya 2016
87

We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Apr 12, 2017

Download

Technology

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: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

We broke up with the Monolith, and started dating Event SourcingMigrations, Event Sourcing, AWS, and other Demeter things

@JavierCane#symfonyCat - Symfony Catalunya 2016

Page 2: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

@JavierCane

Saliendo del monolito, al Rico EventitoMigraciones, Event Sourcing, y otras cosas del meter

#symfonyCat - Symfony Catalunya 2016

Page 3: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Welcome!I’m Javier Ferrer González

@JavierCane

Page 4: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Greetings to Sergi!@SergiGP

Welcome!

Page 5: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Contents

1. Starting point 2. Needs 3. Migration action plan 4. Sync flow example 5. Error handling 6. Issues found 7. Conclusions

Page 6: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

1. Starting point

Context

Page 7: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Mobile first product

Page 8: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat
Page 9: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat
Page 10: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat
Page 11: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat
Page 12: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Starting point Mobile first app

! In-house REST API

◕ symfony/symfony

◕ friendsofsymfony/rest-bundle

◕ jms/serializer

◕ nelmio/api-doc-bundle

Page 13: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Massive growth

Page 14: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Starting point Where do we come

! Startup with less than 2 years

◕ Externalize services (Parse, Kahuna) ! Funding: $200M

◕ Ads on TV in USA and Turkey

Page 15: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Starting point Where do we go

! Microservices architecture ! Event Sourcing ! Orchestration Layer

Page 16: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

2. Needs

New chat system!

Page 17: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat
Page 18: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Needs New chat system!

! From:

◕ REST API

◕ “Chat” (messaging system, polling) ! To:

◕ WebSockets

◕ Chat (real time, push)

◕ Service isolated from the main API

◕ Backwards Compatible (mobile!)

◕ Scale! ! QA tested, Coming to a theater near you!

Page 19: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Needs New chat system!

! To:

◕ WebSockets

◕ Chat (real time, push)

◕ Service isolated from the main API

◕ Backwards Compatible (mobile!)

◗ Not loosing anyone

◗ Enables a “soft migration”

◕ Scale! ! QA tested, Coming to a theater near you!

Page 20: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

3. Migration action plan

Maintaining BC

Page 21: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Migration action plan Maintaining BC

! Develop new chat with Scala and Akka, and WS ! Maintain BC taking advantage of Event Sourcing

Page 22: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Migration action plan Maintaining BC

Page 23: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Migration action plan Maintaining BC

Page 24: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

! Why not share DB?

◕ Limit scheme modifications for the new chat

◕ Chaos

◕ Coupling

Migration action plan Maintaining BC

Page 25: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Migration action plan Maintaining BC

Page 26: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

! SQS: Amazon Simple Queue Service

◕ Managed message queuing service

◕ Transmit any volume of data, at any level of throughput, without losing messages or requiring other services to be always available

! Why not sync through SQS?

◕ Coupling

◗ 2 subscribers => publish to 2 SQS

Migration action plan Maintaining BC

Page 27: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Migration action plan Maintaining BC

Page 28: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

! SNS: Amazon Simple Notification Service

◕ Send push messages to subscribers (no polling)

◕ Scale as your needs grow ! Why sync through SNS?

◕ Decoupled

◗ N subscribers => publish to 1 SNS

◗ Open-Closed Principle compliant at a services level

Migration action plan Maintaining BC

Page 29: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

! 1 SNS per microservice

◕ SNS per event: Too much detail. New event => New SNS

◕ Unique SNS: Not enough detail. Too much noise on the subscribed SQS

Migration action plan Maintaining BC

Page 30: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync

conas asequence

Page 31: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat
Page 32: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat
Page 33: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Migration action plan Maintaining BC

! Delete all messages coming from the legacy chat on the SQS until day X

! Migrate all conversations and messages from day 0 to X using a script

! Start consuming the SQS

Page 34: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

4. Sync flow example

Maintaining BC

Page 35: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Events anatomy

Page 36: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

! 301 @dsamblas

Page 37: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

{ "data": { "id": uuid, "type": "conversation_archived", "attributes": { "conversation_id": uuid, "talker_id": uuid, "archived_at": timestamp, }, "meta" : { "created_at": timestamp, "from_legacy": bool }

First level: “protocol” data

Page 38: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

"data": { "id": uuid, "type": "conversation_archived", "attributes": { "conversation_id": uuid, "talker_id": uuid, "archived_at": timestamp, }, "meta" : { "created_at": timestamp, "from_legacy": bool } }}

Domain aggregate data

Page 39: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

"id": uuid, "type": "conversation_archived", "attributes": { "conversation_id": uuid, "talker_id": uuid, "archived_at": timestamp, }, "meta" : { "created_at": timestamp, "from_legacy": bool } }}

Event metadata

Page 40: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

From the new chat to the legacy one

Page 41: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

Page 42: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

Page 43: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

Page 44: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

Page 45: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

Page 46: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the new chat to the legacy one

Page 47: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

From the legacy chat to the new one

Page 48: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 49: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 50: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 51: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 52: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 53: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 54: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 55: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 56: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Sync flow example From the legacy chat to the new one

Page 57: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

5. Error Handling

Page 58: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Order not guaranteed

Page 59: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Error handling Order not guaranteed

Page 60: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Error handling Order not guaranteed

Page 61: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Error handling Order not guaranteed

Conversation does not exists!

Page 62: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Eventuallyconsistent

Page 63: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Conv. archivedConv. archived

Get items

Conv. archived

Archive conv.

Error handling Order not guaranteed

Conv. createdConv. created

Conv. created

Page 64: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Conv. archivedConv. archived

Get items

Conv. archived

Archive conv.

Error handling Order not guaranteed

Conv. createdConv. created

Conv. createdLets queue it with ‘++$attempts;’

Page 65: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Conv. archivedConv. archived

Get items

Conv. archived

Archive conv.

Error handling Order not guaranteed

Conv. createdConv. created

Conv. created

Create conv.Conv. archived’

Get items

Conv. archived’ Archive conv.

Page 66: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

! If we find an error processing an event =>

◕ Increment its processing attempts and queue it again ! If the number of processing attempts is greater than 5 =>

◕ Queue it into a dead letter SQS ! Symfony command in order to reprocess the dead letter

Error handling Order not guaranteed

Page 67: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

SQS: Message duplication

Page 68: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Let itcrash

Page 69: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Identity generation

Page 70: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Error handling Identity generation

Conv. created

Message sentConv. created

Message sentGet items

Conv. created

Message sent

Send message

Page 71: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Error handling Identity generation

Conv. created

Message sentConv. created

Message sentGet items

Conv. created

Message sent

Send message

Conversation does not exists! Lets create it with ID ‘b’!

Page 72: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Error handling Identity generation

Conv. created

Message sentConv. created

Message sentGet items

Conv. created

Message sent

Create conv.

Send message

Conversation does not exists! Lets create it with ID ‘b’!

Lets create the conversation ‘a’!

Page 73: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

“ Generating identifiers from the inside is a side effect. Side effects difficult testing.

Page 74: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

“ If you generate IDs from the inside, you are not being SRP compliant.

Page 75: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

6. Issues found

Page 76: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Issues found SQS -> SNS

! Order not guaranteed & events duplication ! Alternatives:

◕ RabbitMQ

◗ Why not: go fast & don’t worry about clusters

◕ Kafka

◗ Why not: Same as RabbitMQ

◗ BTW: Order guaranteed, no duplication, partitions

◕ Kinesis

◗ Why not: More expensive

◗ BTW: Order guaranteed, no duplication, partitions

◕ Furthermore: Do not add more uncertainty

Page 77: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Issues found Initial data migration

! Source DB node: Slave outside the production LB ! Destination DB node: Increase AWS provisioned IOPS

Page 78: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

#basuritas

Page 79: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Issues found Not following SRP

! REST API

◕ Send message endpoint => create conversation if not exists. #basuritas

◕ GET conversation messages => mark messages as read

◗ Check if a conversation exists, new endpoint: ”HEAD /conversation/{id}”

Page 80: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

7. Conclusions

Page 81: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Conclusions

! Event Sourcing ~~ DIP at a services level

◕ Dependency Inversion Principle (CodelyTV video)

◕ Allow OCP: One SNS publishes to many SQS

◕ Encourage SRP

◕ Decoupleeeeee

Page 82: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Conclusions

! Event Sourcing ~~ DIP at a services level

◕ Dependency Inversion Principle (CodelyTV video)

◕ Allow OCP: One SNS publishes to many SQS

◕ Encourage SRP

◕ Decoupleeeeee

Page 83: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Conclusions

! Isolated services

◕ Different technologies

◕ Different contexts

◕ Change context -> Mental challenge

! From PHP to Scala: 🙃 🙂 🙃 💃 🙃 😀 😐 😳 🤔 🙂 🙃 🙂 …

! Know more at #SCBCN16! (October 1st & 2nd in BCN) ! A lot of work, if you want to deal with that, we're hiring!

Page 84: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Conclusions

Page 85: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

References / To take away

! A Series of Fortunate Events ! The anatomy of Domain Event ! 6 Code Smells with your CQRS Events and How to Avoid Them ! json:api standard ! Sending Amazon SNS Messages to Amazon SQS Queues ! Subscribing a Queue to an Amazon SNS Topic

Page 86: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Questions?

Thanks!Contact @JavierCane || @SergiGP [email protected] Codely.TV

Page 87: We broke up with the monolith, and started dating #eventSourcing - #symfonyCat

Credits

! Presentation base template by SlidesCarnival ! Graphics generated using draw.io ! Icon set Small-n-flat ! A Series of Fortunate Events