dr. roland kuhn: reactive design patterns
TRANSCRIPT
![Page 1: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/1.jpg)
Reactive Design PatternsDr. Roland Kuhn
@rolandkuhn — Akka Tech Lead
![Page 2: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/2.jpg)
Reactive Design Patterns
• currently in MEAP
• all chapters in review now
• use code 39kuhn (39% off)
2
![Page 3: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/3.jpg)
Reactive?
![Page 4: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/4.jpg)
Elasticity: Performance at Scale
4
![Page 5: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/5.jpg)
Resilience: Don’t put all eggs in one basket!
5
![Page 6: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/6.jpg)
Result: Responsiveness
• elastic components that scale with their load
• responses in the presence of partial failures
6
![Page 7: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/7.jpg)
Result: Decoupling
• containment of • failures
• implementation details
• responsibility
• shared-nothing architecture, clear boundaries
7
![Page 8: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/8.jpg)
Result: Maintainability & Fexibility
• decoupled responsibility—decoupled teams
• develop pieces at their own pace
• continuous delivery
• Microservices: Single Responsibility Principle
8
![Page 9: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/9.jpg)
Implementation: Message-Driven
• focus on communication between components
• model message flows and protocols
• common transports: async HTTP, *MQ, Actors
9
![Page 10: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/10.jpg)
Reactive Traits
10
elastic resilient
responsive maintainable extensible
message-‐driven
Value
Means
Form
![Page 11: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/11.jpg)
Architecture Patterns
![Page 12: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/12.jpg)
Simple Component Pattern
12
«A component shall do only one thing,
but do it in full.»
![Page 13: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/13.jpg)
Simple Component Pattern
• Single Responsibility Principle formulated by DeMarco in «Structured analysis and system specification» (Yourdon, New York, 1979) • “maximize cohesion and minimize coupling”
• “a class should have only one reason to change”(Uncle Bob Martin’s formulation for OOD)
13
![Page 14: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/14.jpg)
Example: the Batch Job Service
• users submit jobs
• planning and validation rules
• execution on elastic compute cluster
• users query job status and results
14
![Page 15: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/15.jpg)
Example: the Batch Job Service
15
![Page 16: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/16.jpg)
Example: the Batch Job Service
16
![Page 17: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/17.jpg)
Example: the Batch Job Service
17
![Page 18: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/18.jpg)
Let-It-Crash Pattern
18
«Prefer a full component restart to
complex internal failure handling.»
![Page 19: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/19.jpg)
Let-It-Crash Pattern
• Candea & Fox: “Crash-Only Software”(USENIX HotOS IX, 2003)
• transient and rare failures are hard to detect and fix
• write component such that full restart is always o.k.
• simplified failure model leads to more reliability
19
![Page 20: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/20.jpg)
Let-It-Crash Pattern
• Erlang philosophy from day one
• popularized by Netflix Chaos Monkey • make sure that system is resilient by arbitrarily performing
recovery restarts
• exercise failure recovery code paths for real
• failure will happen, fault-avoidance is doomed
20
![Page 21: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/21.jpg)
Implementation Patterns
![Page 22: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/22.jpg)
Circuit Breaker Pattern
22
«Protect services by breaking the
connection during failure periods.»
![Page 23: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/23.jpg)
Circuit Breaker Pattern
• well-known, inspired by electrical engineering
• first published by M. Nygard in «Release It!»
• protects both ways: • allows client to avoid long failure timeouts
• gives service some breathing room to recover
23
![Page 24: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/24.jpg)
Circuit Breaker Example
24
private object StorageFailed extends RuntimeExceptionprivate def sendToStorage(job: Job): Future[StorageStatus] = { // make an asynchronous request to the storage subsystem val f: Future[StorageStatus] = ??? // map storage failures to Future failures to alert the breaker f.map { case StorageStatus.Failed => throw StorageFailed case other => other }}
private val breaker = CircuitBreaker( system.scheduler, // used for scheduling timeouts 5, // number of failures in a row when it trips 300.millis, // timeout for each service call 30.seconds) // time before trying to close after tripping
def persist(job: Job): Future[StorageStatus] = breaker .withCircuitBreaker(sendToStorage(job)) .recover { case StorageFailed => StorageStatus.Failed case _: TimeoutException => StorageStatus.Unknown case _: CircuitBreakerOpenException => StorageStatus.Failed }
![Page 25: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/25.jpg)
Multiple-Master Replication Patterns
25
«Keep multiple distributed copies,
accept updates everywhere,
disseminate updates among replicas.»
![Page 26: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/26.jpg)
Multiple-Master Replication Patterns
• this is a tough problem with no perfect solution
• requires a trade-off to be made between consistency and availability • consensus-based focuses on consistency
• conflict-free focuses on availability
• conflict resolution gives up a bit of both
• each requires a different programming model and can express different transactional behavior
26
![Page 27: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/27.jpg)
Consensus-Based Replication
• strong coupling between replicas to ensure that all are “on the same page”
• unavailable during network outages or certain machine failures
• programming model “just like a single thread”
• Postgres, Zookeeper, etc.
27
![Page 28: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/28.jpg)
Replication with Conflict Resolution
• requires conflict detection
• resolution without user intervention will have to discard some updates
• detection/resolution unavailable during partitions
• programming model “like single thread” with caveat
• popular RDBMS in default configuration offer this
28
![Page 29: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/29.jpg)
Conflict-Free Replication
• express updates such that they can be merged
• cannot express “non-local” constraints
• all expressible updates can be performed under any conditions without losses or inconsistencies
• replicas may temporarily be out of sync
• different programming model, explicitly distributed
• Riak 2.0, Akka Distributed Data
29
![Page 30: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/30.jpg)
Multiple-Master Replication Patterns
• no one size fits all
• you will have to think and decide!
30
![Page 31: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/31.jpg)
Saga Pattern
31
«Divide long-lived distributed
transactions into quick local ones with
compensating actions for recovery.»
![Page 32: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/32.jpg)
Saga Pattern: Background
• Microservice Architecture means distribution of knowledge, no more central database instance
• Pat Helland: • “Life Beyond Distributed Transactions”, CIDR 2007
• “Memories, Guesses, and Apologies”, MSDN blog 2007
• What about transactions that affect multiple microservices?
32
![Page 33: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/33.jpg)
Saga Pattern
• Garcia-Molina & Salem: “SAGAS”, ACM, 1987
• Bank transfer avoiding lock of both accounts: • T₁: transfer money from X to local working account
• T₂: transfer money from local working account to Y
• C₁: compensate failure by transferring money back to X
• Compensating transactions are executed during Saga rollback
• concurrent Sagas can see intermediate state
33
![Page 34: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/34.jpg)
Saga Pattern
• backward recovery:T₁ T₂ T₃ C₃ C₂ C₁
• forward recovery with save-points:T₁ (sp) T₂ (sp) T₃ (sp) T₄
• in practice Sagas need to be persistent to recover after hardware failures, meaning backward recovery will also use save-points
34
![Page 35: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/35.jpg)
Example: Bank Transfer
35
trait Account { def withdraw(amount: BigDecimal, id: Long): Future[Unit] def deposit(amount: BigDecimal, id: Long): Future[Unit]}
case class Transfer(amount: BigDecimal, x: Account, y: Account)
sealed trait Eventcase class TransferStarted(amount: BigDecimal, x: Account, y: Account) extends Eventcase object MoneyWithdrawn extends Eventcase object MoneyDeposited extends Eventcase object RolledBack extends Event
![Page 36: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/36.jpg)
Example: Bank Transfer
36
class TransferSaga(id: Long) extends PersistentActor { import context.dispatcher
override val persistenceId: String = s"transaction-$id"
override def receiveCommand: PartialFunction[Any, Unit] = { case Transfer(amount, x, y) => persist(TransferStarted(amount, x, y))(withdrawMoney) }
def withdrawMoney(t: TransferStarted): Unit = { t.x.withdraw(t.amount, id).map(_ => MoneyWithdrawn).pipeTo(self) context.become(awaitMoneyWithdrawn(t.amount, t.x, t.y)) }
def awaitMoneyWithdrawn(amount: BigDecimal, x: Account, y: Account): Receive = { case m @ MoneyWithdrawn => persist(m)(_ => depositMoney(amount, x, y)) }
...}
![Page 37: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/37.jpg)
Example: Bank Transfer
37
def depositMoney(amount: BigDecimal, x: Account, y: Account): Unit = { y.deposit(amount, id) map (_ => MoneyDeposited) pipeTo self context.become(awaitMoneyDeposited(amount, x))}
def awaitMoneyDeposited(amount: BigDecimal, x: Account): Receive = { case Status.Failure(ex) => x.deposit(amount, id) map (_ => RolledBack) pipeTo self context.become(awaitRollback) case MoneyDeposited => persist(MoneyDeposited)(_ => context.stop(self))}
def awaitRollback: Receive = { case RolledBack => persist(RolledBack)(_ => context.stop(self))}
![Page 38: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/38.jpg)
Example: Bank Transfer
38
override def receiveRecover: PartialFunction[Any, Unit] = { var start: TransferStarted = null var last: Event = null
{ case t: TransferStarted => { start = t; last = t } case e: Event => last = e case RecoveryCompleted => last match { case null => // wait for initialization case t: TransferStarted => withdrawMoney(t) case MoneyWithdrawn => depositMoney(start.amount, start.x, start.y) case MoneyDeposited => context.stop(self) case RolledBack => context.stop(self) } }}
![Page 39: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/39.jpg)
Saga Pattern: Reactive Full Circle
• Garcia-Molina & Salem note: • “search for natural divisions of the work being performed”
• “it is the database itself that is naturally partitioned into relatively independent components”
• “the database and the saga should be designed so that data passed from one sub-transaction to the next via local storage is minimized”
• fully aligned with Simple Components and isolation
39
![Page 40: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/40.jpg)
Conclusion
![Page 41: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/41.jpg)
Conclusion
• reactive systems are distributed
• this requires new (old) architecture patterns
• … helped by new (old) code patterns & abstractions
• none of this is dead easy: thinking is required!
41
![Page 42: Dr. Roland Kuhn: Reactive Design Patterns](https://reader033.vdocument.in/reader033/viewer/2022042907/587f066d1a28abc26f8b4e75/html5/thumbnails/42.jpg)
REACTIVE PLATFORMFull Lifecycle Support for Play, Akka, Scala and Spark
Give your project a boost with Reactive Platform:
• Monitor Message-Driven Apps • Resolve Network Partitions Decisively • Integrate Easily with Legacy Systems • Eliminate Incompatibility & Security Risks • Protect Apps Against Abuse • Expert Support from Dedicated Product Teams
Enjoy learning? See about the availability of on-site training for Scala, Akka, Play and Spark!
Learn more about our offersCONTACT US