Slide 1

Slide 1 text

%FWFMPQJOH.JDSPTFSWJDFT
 XJUI"HHSFHBUFT d4QSJOH0OF1MBUGPSNใࠂձ ೔ຊ+BWBϢʔβʔάϧʔϓ
 "DSPRVFTU5FDIOPMPHZגࣜձࣾ ୩ຊ৺ !DFSP@U

Slide 2

Slide 2 text

ࣗݾ঺հ ͖ͬ͞͠·ͨ͠

Slide 3

Slide 3 text

๻ͷதͰͷ
 4QSJOH0OF
 ϕετηογϣϯ

Slide 4

Slide 4 text

-FUT7JTVBMJ[F:PVS
 4QSJOH#PPU"QQMJDBUJPOT Acroquest Technology Co., LTD.
 Shin Tanimoto (@cero_t)

Slide 5

Slide 5 text

͡Όͳͯ͘

Slide 6

Slide 6 text

@crichardson Developing Microservices with Aggregates Chris Richardson Founder of Eventuate.io Founder of the original CloudFoundry.com Author of POJOs in Action @crichardson [email protected] http://eventuate.io

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

ϚΠΫϩαʔϏεΛ
 %%%ͷυϝΠϯ୯ҐͰ
 ࡞Δ΂͖ͩͱ͔
 τϥϯβΫγϣϯͲ͏͢Δ
 ͱ͔ͷ࿩

Slide 9

Slide 9 text

Ωʔϫʔυ
 
 %%%
 Πϕϯτιʔγϯά
 $234

Slide 10

Slide 10 text

Α͘෼͔Βͳ͔ͬͨΜͰ
 ؼࠃ͔ͯ͠Β΋ؚΊͯ
 ϲ݄͙Β͍ߟ͑ଓ͚ͯΔ

Slide 11

Slide 11 text

@crichardson Microservice architecture Browser Mobile Device Store Front UI API Gateway Catalog Service Review Service Order Service … Service Catalog Database Review Database Order Database … Database HTML REST REST Apply X-axis and Z-axis scaling to each service independently

Slide 12

Slide 12 text

%#Λ෼͚ͪΌͬͨΒ ෳ਺υϝΠϯͷࢀরͬͯ
 Ͳ͏΍Ε͹͍͍ͷʁ

Slide 13

Slide 13 text

@crichardson Product service Customer service Order service Domain model = tangled web of classes Order OrderLine Item quantity … Address street city … Customer Product name price ? ? creditLimit

Slide 14

Slide 14 text

@crichardson But it violates encapsulation… BEGIN TRANSACTION … SELECT ORDER_TOTAL FROM ORDERS WHERE CUSTOMER_ID = ? … SELECT CREDIT_LIMIT FROM CUSTOMERS WHERE CUSTOMER_ID = ? … INSERT INTO ORDERS … … COMMIT TRANSACTION Private to the Order Service Private to the Customer Service

Slide 15

Slide 15 text

@crichardson 2PC is not a viable option Guarantees consistency BUT 2PC is best avoided Not supported by many NoSQL databases etc. CAP theorem 㱺 2PC impacts availability ….

Slide 16

Slide 16 text

1$ͬͯදݱ
 ΧοίΠΠ

Slide 17

Slide 17 text

͡Όͳͯ͘

Slide 18

Slide 18 text

1$͸
 ͜ͷઌੜ͖ͷ͜Δ
 બ୒ࢶͰ͸ͳ͍

Slide 19

Slide 19 text

@crichardson 2PC is not a viable option Guarantees consistency BUT 2PC is best avoided Not supported by many NoSQL databases etc. CAP theorem 㱺 2PC impacts availability ….

Slide 20

Slide 20 text

@crichardson Aggregate rule #2 Transaction = processing one command by one aggregate

Slide 21

Slide 21 text

ճͷϚΠΫϩαʔϏείʔϧ τϥϯβΫγϣϯൣғ /P42-ͷτϥϯβΫγϣϯ

Slide 22

Slide 22 text

@crichardson Aggregate granularity If an update must be atomic then it must be handled by a single aggregate Therefore Aggregate granularity is important

Slide 23

Slide 23 text

ͦΜͳ͜ͱ͸
 ෼͔ͬͯΔ

Slide 24

Slide 24 text

@crichardson Aggregate granularity Consistency Scalability/ User experience Customer Order Product Customer Order Product Customer Order Product

Slide 25

Slide 25 text

͔ͩΒɺͲ͏͢Δͷʁ

Slide 26

Slide 26 text

@crichardson Customer management How to maintain data consistency between aggregates? Order management Order Service placeOrder() Customer Service updateCreditLimit() Customer creditLimit ... has orders belongs to Order total Invariant: sum(open order.total) <= customer.creditLimit ?

Slide 27

Slide 27 text

@crichardson Use event-driven, eventually consistent order processing Order Service Customer Service Order created Credit Reserved Credit Check Failed Create Order OR Customer creditLimit creditReservations ... Order state total … create() reserveCredit() approve()/reject()

Slide 28

Slide 28 text

ΠϕϯτυϦϒϯΛ༻͍ͨ
 ݁Ռ੔߹ੑ

Slide 29

Slide 29 text

ΦʔμʔαʔϏεͰΦʔμʔ࡞੒
 ˣ
 ܾࡁαʔϏεͰܾࡁ࡞੒
 ˣ
 ΦʔμʔαʔϏεͰॲཧܧଓ

Slide 30

Slide 30 text

ͳΔ΄Ͳɺ෼͔Βͳ͘͸ͳ͍

Slide 31

Slide 31 text

͋ΕɺͰ΋

Slide 32

Slide 32 text

@crichardson How atomically update database and publish an event Order Service Order Database Message Broker insert Order publish OrderCreatedEvent dual write problem ?

Slide 33

Slide 33 text

@crichardson 2PC is not an option

Slide 34

Slide 34 text

Πϕϯτιʔγϯά

Slide 35

Slide 35 text

@crichardson Event sourcing = event-centric persistence Application Database Event store update publish X

Slide 36

Slide 36 text

%#Λߋ৽͢ΔͷͰ͸ͳ͍ɺ
 ΠϕϯτΛอଘ͢ΔΜͩɻ

Slide 37

Slide 37 text

@crichardson Persists events NOT current state Event table Entity type Event id Entity id Event data Order 902 101 … OrderApproved Order 903 101 … OrderShipped Event type Order 901 101 … OrderCreated

Slide 38

Slide 38 text

@crichardson The present is a fold over history currentState = foldl(applyEvent, initialState, events)

Slide 39

Slide 39 text

ۃ୺ʹݴ͑͹
 ʮ͜ΕΛߪೖͨ͠ʯ͍ͬͯ͏
 Πϕϯτ͚ͩอଘ͓͚ͯ͠͹
 ͋ͱͷঢ়ଶ͸͔ͦ͜Βશ෦
 ܭࢉͰ͖ΔΑͶɺͬͯ࿩ɻ

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

͔͜͜Βઌͷηογϣϯ͸
 ͍·ͩʹཧղͰ͖ͳ͍ͷͰ
 ཧղͨ͠ͱ͜Ζ·Ͱͷ࿩ɻ

Slide 42

Slide 42 text

ہॴతͳΠϕϯτιʔγϯά͸
 ͔֬ʹ੒Γཱͭ

Slide 43

Slide 43 text

γϣοϐϯάΧʔτ

Slide 44

Slide 44 text

.&5"-3&4*45"/$&௥Ճ
 50,:0%0.&.&.03*"-5&&௥Ճ #"#:.&5"-དྷ೔ه೦൫௥Ճ
 #"#:.&5"-དྷ೔ه೦൫࡟আ
 ˣ .&5"-3&4*45"/$&
 50,:0%0.&.&.03*"-5&& #"#:.&5"-དྷ೔ه೦൫

Slide 45

Slide 45 text

ॱ൪͸ؔ܎ͳ͘
 ݁Ռ੔߹ੑϕʔεͰߟ͑Δ

Slide 46

Slide 46 text

#"#:.&5"-དྷ೔ه೦൫࡟আ
 #"#:.&5"-དྷ೔ه೦൫௥Ճ
 ˣ #"#:.&5"-དྷ೔ه೦൫ 
 #"#:.&5"-དྷ೔ه೦൫

Slide 47

Slide 47 text

݁Ռ੔߹ͩͱͯ͠΋ɺ
 Ͳ͏ू໿͢Δ͔͸ϙϦγʔ࣍ୈɻ
 
 γϣοϐϯάΧʔτͰ͋Ε͹
 ʮ࠷ऴతͳঢ়ଶʯΛ
 Ϣʔβʹ֬ೝ͢Δ͜ͱ͕ඞਢ

Slide 48

Slide 48 text

ݫີ͕͔ܽͤ͞ͳ͍ͳΒ
 "$*%ͳ3%#.4Λ࢖͏͔͠ͳ͍

Slide 49

Slide 49 text

ԁೖۚ
 ԁҾग़
 ԁҾग़ ˣ ͍΍͍΍ɺԁҾ͖ग़͢ॴͰ
 /(Ͱ͠ΐ

Slide 50

Slide 50 text

ԁೖۚ
 ԁҾग़
 ԁҾग़ ˣ ࢒ߴԁ

Slide 51

Slide 51 text

Πϕϯτιʔγϯά೴Ͱߟ͑
 ͦͷ௨Γʹۀ຿ཁ݅ΛدͤΔ
 
 Ͳ͏ͯ͠΋μϝͳॴ͚ͩ
 3%#.4Λ࢖͏

Slide 52

Slide 52 text

Πϕϯτιʔγϯά͸
 εςʔτιʔγϯάʹൺ΂ͯ
 $234Λ࣮ݱ͠΍͍͢

Slide 53

Slide 53 text

$234
 $PNNBOE
 2VFSZ
 3FTQPOTJCJMJUZ
 4FHSFHBUJPO

Slide 54

Slide 54 text

ճͷॲཧ͸
 ߋ৽͔ݕࡧͷยํ͚ͩʹ͢Δ

Slide 55

Slide 55 text

4&-&$5CBMBODF
 '30.BDDPVOU
 '0361%"5&
 ˣ
 61%"5&BDDPVOU
 4&5CBMBODF

Slide 56

Slide 56 text

*/4&35*/50CBMBODF@FWFOU
 FWFOU BNPVOU 
 WBMVFT bXJUIESBX`

Slide 57

Slide 57 text

݁Ռ੔߹ੑϕʔεͷ
 /P42-ͱ΋૬ੑ͕ྑ͍

Slide 58

Slide 58 text

ͪͳΈʹࢿྉʹ໭Δͱ

Slide 59

Slide 59 text

@crichardson Request handling in an event sourced application HTTP Handler Event Store pastEvents = findEvents(entityId) Order new() applyEvents(pastEvents) newEvents = processCmd(someCmd) saveEvents(newEvents) (optimistic locking) Order Service applyEvents(newEvents)

Slide 60

Slide 60 text

ͳΜͰBQQMZ&WFOUΛ
 &WFOU4UPSFˠ0SEFS
 ʹ͠ͳ͍ΜͩΖʁ

Slide 61

Slide 61 text

@crichardson Event Store publishes events consumed by other services Event Store Event Subscriber subscribe(EventTypes) publish(event) publish(event) Customer update() Customer Service

Slide 62

Slide 62 text

@crichardson Event Store publishes events consumed by other services Event Store Event Subscriber subscribe(EventTypes) publish(event) publish(event) CQRS View update() Service Xyz send notifications …

Slide 63

Slide 63 text

@crichardson The Customer aggregate Money creditLimit Map creditReservations Customer List process(CreateCustomerCommand cmd) { … } List process(ReserveCreditCommand cmd) { … } … void apply(CustomerCreatedEvent anEvent) { … } void apply(CreditReservedEvent anEvent) { … } … State Behavior

Slide 64

Slide 64 text

@crichardson Familiar concepts restructured class Customer { public void reserveCredit( orderId : String, amount : Money) { // verify // update state this.xyz = … } public List process( ReserveCreditCommand cmd) { // verify … return singletonList( new CreditReservedEvent(…); ) } public void apply( CreditReservedEvent event) { // update state this.xyz = event.xyz }

Slide 65

Slide 65 text

@crichardson Customer command processing

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

·ͱΊ

Slide 68

Slide 68 text

υϝΠϯ͝ͱʹαʔϏεΛ෼͚Δ
 
 ϚΠΫϩαʔϏεʹର͢ΔϦΫΤετ͸
 ͦͷ··τϥϯβΫγϣϯʹͳΔ 1$͸΋͏࢖Θͳ͍

Slide 69

Slide 69 text

ʮঢ়ଶʯΛߋ৽͠ͳ͍ ʮΠϕϯτʯΛ௥Ճ͢Δ ʮঢ়ଶʯ͸ʮΠϕϯτʯͷ
 ஝ੵ͔Β൑அ͢Δ
 
 ʢΠϕϯτιʔγϯά$234ʣ

Slide 70

Slide 70 text

Πϕϯτιʔγϯά΍$234͸
 /P42-ʢ݁Ռ੔߹ੑʣϕʔεͷ
 ϚΠΫϩαʔϏεͷ։ൃʹ
 ͔ܽͤͳ͍ߟ͑ํͱͳΔ

Slide 71

Slide 71 text

Ұॹʹษڧ͍͖ͯ͠·͠ΐ͏ʂ