Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[SpringOne2016] Developing Microservices with Aggregates

Ad3fbc316f916a341c24035e34913121?s=47 Shin Tanimoto
September 03, 2016

[SpringOne2016] Developing Microservices with Aggregates

SpringOne Platform 2016報告会

Ad3fbc316f916a341c24035e34913121?s=128

Shin Tanimoto

September 03, 2016
Tweet

Transcript

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

  2. ࣗݾ঺հ ͖ͬ͞͠·ͨ͠

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

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

  5. ͡Όͳͯ͘

  6. @crichardson Developing Microservices with Aggregates Chris Richardson Founder of Eventuate.io

    Founder of the original CloudFoundry.com Author of POJOs in Action @crichardson chris@chrisrichardson.net http://eventuate.io
  7. None
  8. ϚΠΫϩαʔϏεΛ
 %%%ͷυϝΠϯ୯ҐͰ
 ࡞Δ΂͖ͩͱ͔
 τϥϯβΫγϣϯͲ͏͢Δ
 ͱ͔ͷ࿩

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

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

  11. @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
  12. %#Λ෼͚ͪΌͬͨΒ ෳ਺υϝΠϯͷࢀরͬͯ
 Ͳ͏΍Ε͹͍͍ͷʁ

  13. @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
  14. @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
  15. @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 ….
  16. 1$ͬͯදݱ
 ΧοίΠΠ

  17. ͡Όͳͯ͘

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

  19. @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 ….
  20. @crichardson Aggregate rule #2 Transaction = processing one command by

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

  22. @crichardson Aggregate granularity If an update must be atomic then

    it must be handled by a single aggregate Therefore Aggregate granularity is important
  23. ͦΜͳ͜ͱ͸
 ෼͔ͬͯΔ

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

    Customer Order Product Customer Order Product
  25. ͔ͩΒɺͲ͏͢Δͷʁ

  26. @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 ?
  27. @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()
  28. ΠϕϯτυϦϒϯΛ༻͍ͨ
 ݁Ռ੔߹ੑ

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

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

  31. ͋ΕɺͰ΋

  32. @crichardson How atomically update database and publish an event Order

    Service Order Database Message Broker insert Order publish OrderCreatedEvent dual write problem ?
  33. @crichardson 2PC is not an option

  34. Πϕϯτιʔγϯά

  35. @crichardson Event sourcing = event-centric persistence Application Database Event store

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

  37. @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
  38. @crichardson The present is a fold over history currentState =

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

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

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

  43. γϣοϐϯάΧʔτ

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

    
 50,:0%0.&.&.03*"-5&&  #"#:.&5"-དྷ೔ه೦൫ 
  45. ॱ൪͸ؔ܎ͳ͘
 ݁Ռ੔߹ੑϕʔεͰߟ͑Δ

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

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

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

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

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

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

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

  53. $234
 $PNNBOE
 2VFSZ
 3FTQPOTJCJMJUZ
 4FHSFHBUJPO

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

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

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

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

  58. ͪͳΈʹࢿྉʹ໭Δͱ

  59. @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)
  60. ͳΜͰBQQMZ&WFOUΛ
 &WFOU4UPSFˠ0SEFS
 ʹ͠ͳ͍ΜͩΖʁ

  61. @crichardson Event Store publishes events consumed by other services Event

    Store Event Subscriber subscribe(EventTypes) publish(event) publish(event) Customer update() Customer Service
  62. @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 …
  63. @crichardson The Customer aggregate Money creditLimit Map<OrderId, Money> creditReservations Customer

    List<Event> process(CreateCustomerCommand cmd) { … } List<Event> process(ReserveCreditCommand cmd) { … } … void apply(CustomerCreatedEvent anEvent) { … } void apply(CreditReservedEvent anEvent) { … } … State Behavior
  64. @crichardson Familiar concepts restructured class Customer { public void reserveCredit(

    orderId : String, amount : Money) { // verify // update state this.xyz = … } public List<Event> process( ReserveCreditCommand cmd) { // verify … return singletonList( new CreditReservedEvent(…); ) } public void apply( CreditReservedEvent event) { // update state this.xyz = event.xyz }
  65. @crichardson Customer command processing

  66. None
  67. ·ͱΊ

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

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

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

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