Spring BootとKafkaでCQRS

Spring BootとKafkaでCQRS

JJUG CCC 2017 FALL

979f8815a9d4604d87f54b8394c503bd?s=128

Mitsuyuki Shiiba

November 18, 2017
Tweet

Transcript

  1. Spring BootとKafkaでCQRS Nov.18.2017 at JJUG CCC 2017 Fall Mitsuyuki Shiiba

    EC Incubation Development Department. Rakuten, Inc.
  2. #ccc_e6 Mitsuyuki Shiiba(@bufferings) 関ジャバの⽅から来ました!!

  3. #ccc_e6 Mitsuyuki Shiiba(@bufferings) 好き • Java、Scrum、DDD、娘

  4. #ccc_e6 Mitsuyuki Shiiba(@bufferings) 仕事 • 楽天株式会社 ⼤阪⽀社(2010〜) • ウェブアプリケーションエンジニア •

    ECインキュベーション開発部 仲間募集中ですー!興味ある⽅は連絡くださいー! 「解決してあげることが改善ではない」20年のWeb開発から⽣ま れた、楽天式"カイゼン"とは。 https://teratail.com/report/3
  5. #ccc_e6 CQRS? • 聞いたことある? • 知ってる? • 使ったことある? ほとんどの⼈がCQRSって聞いたことはあって、それが何かって ことを知ってる⼈は3割くらいいたけど、使ったことある⼈はほと

    んどいなかったね。
  6. #ccc_e6 CQRS Command and Query Responsibility Segregation コマンドクエリ責務分離 named by

    Greg Young CQS原則(Bertrand Meyer)が起源になってます。 参照: Bliki(ja) “コマンド・問い合わせの分離” http://bliki-ja.github.io/CommandQuerySeparation/
  7. #ccc_e6 CQRS コマンドとクエリを別のオブジェクトに分ける ってどういうこと?

  8. #ccc_e6 CQRS コマンドとクエリを別のオブジェクトに分ける 図はCacooで書きました。すごく使いやすいー。 https://cacoo.com/ja

  9. #ccc_e6 CustomerService void MakeCustomerPreferred(CustomerId) Customer GetCustomer(CustomerId) CustomerSet GetCustomersWithName(Name) CustomerSet GetPreferredCustomers()

    void ChangeCustomerLocale(CustomerId, NewLocale) void CreateCustomer(Customer) void EditCustomerDetails(CustomerDetails) 参照: CQRS, Task Based UIs, Event Sourcing agh! http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis- event-sourcing-agh/ (参照⽇ 2017-11-17)
  10. #ccc_e6 CustomerWriteService void MakeCustomerPreferred(CustomerId) void ChangeCustomerLocale(CustomerId, NewLocale) void CreateCustomer(Customer) void

    EditCustomerDetails(CustomerDetails) 参照: CQRS, Task Based UIs, Event Sourcing agh! http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis- event-sourcing-agh/ (参照⽇ 2017-11-17)
  11. #ccc_e6 CustomerReadService Customer GetCustomer(CustomerId) CustomerSet GetCustomersWithName(Name) CustomerSet GetPreferredCustomers() 参照: CQRS,

    Task Based UIs, Event Sourcing agh! http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis- event-sourcing-agh/ (参照⽇ 2017-11-17)
  12. #ccc_e6 CQRS コマンドとクエリを別のオブジェクトに分ける

  13. #ccc_e6 CQRS これだけ

  14. #ccc_e6 CQRS なんだけど⾯⽩い! これをどうやって実現しようかな?って考え始めると、すごく⾯ ⽩いー。

  15. #ccc_e6 今⽇のお話 • 第1話:僕とDDD • 第2話:僕とCQRS • 第3話:僕とDomain Event •

    第4話:僕とEvent Sourcing • 第5話:僕とCQRS(その2) • 第6話:Spring BootとKafkaでCQRS
  16. #ccc_e6 今⽇のお話 ⾯⽩そうだなと思って僕が勉強してることのお話 CQRSを仕事で実践したって話じゃないよ。

  17. #ccc_e6 今⽇のお話のゴール CQRS⾯⽩そうだね!って 懇親会で話かけてもらえるように頑張る!

  18. #ccc_e6 第1話:僕とDDD Domain Driven Design(ドメイン駆動設計)

  19. #ccc_e6 僕 複雑になっていくシステムをなんとかしたい

  20. #ccc_e6 僕 最初にキレイなシステムを作れたらOK?

  21. #ccc_e6 僕 それでも、だんだん複雑になっていく感じする

  22. #ccc_e6 僕 • 複雑じゃないんだったら、その状態をキープし たい! • 複雑なんだとしても、⽬を背けずにそれを改善 していきたい! ってことは…

  23. #ccc_e6 僕 • 複雑さから逃げるんじゃなくて • 複雑さを避けるんじゃなくて • 複雑さに⽴ち向かわなきゃいけない どうしたらいいんだろう?

  24. #ccc_e6 DDD 「ソフトウェアの核⼼にある 複雑さに⽴ち向かう」 エリック・エヴァンスのドメイン駆動設計(⽇本語訳:2011年) https://books.rakuten.co.jp/rb/11146351/

  25. #ccc_e6 DDD 分からん!!! 10年前くらいに英語版(読めもしないのに!)買って最初のペー ジにある中国の地図だけ⾒てました!2011年に⽇本語版が出て読 んでみてもやっぱり分かりませんでした!

  26. #ccc_e6 DDD 「エリック・エヴァンズが 確⽴した理論を実際の設計に 応⽤する」 実践ドメイン駆動設計(⽇本語訳: 2015年) https://books.rakuten.co.jp/rb/13138730/

  27. #ccc_e6 DDD 少し分かってきたかも! それまでは「⾔ってることは分かるけど、どう実装したらいいん だろう?」っだったんだけど、この本で具体例を教えてくれてる ので「少し分かってきたかも!」ってなったんだった。2015年ま での間に、⾃分⾃⾝が⾊々⾒て成⻑してきたのもあるかな。

  28. #ccc_e6 DDDが⼤切にしていることの⼀つに 依存関係を切り離すことで複雑さを閉じ込めて コントロールできるようにしている部分がある という印象

  29. #ccc_e6 DDD: 境界づけられたコンテキスト コンテキストを切り離す

  30. #ccc_e6 DDD: ドメインモデル DBやUIなどドメインロジックに関係ないことを 切り離す

  31. #ccc_e6 DDD: 集約 他のモデルから切り離す (トランザクションの単位)

  32. #ccc_e6 DDD 凝縮して⼩さく保つことで複雑さに⽴ち向かう 他にも⾊々あるけどね。今⽇関係するのはこのあたり。

  33. #ccc_e6 僕とDDD よっしゃー!やってみるぞー!

  34. #ccc_e6 僕とDDD DBからの解放感。素敵すぎる。 ドメインモデルからDBに関係するものを(アノテーションすら も)切り離したら解放感。リポジトリが頑張ってくれてる。

  35. #ccc_e6 僕とDDD この調⼦でUIからも解放…あれ?ムズい…

  36. #ccc_e6 僕とDDD この調⼦でUIからも解放…あれ?ムズい… • 複数の集約をつないだ情報が必要だったり • 集約から導出した値で検索が必要だったり

  37. #ccc_e6 第1話:僕とDDD 完 ぐぬぬ。。。 ということで、実はJOIN使ったりしてた。

  38. #ccc_e6 第2話:僕とCQRS

  39. #ccc_e6 前回のあらすじ DDDで複雑さに⽴ち向かおうとしたが UI⽤の情報をいい感じに取得できなかった

  40. #ccc_e6 僕とCQRS コマンド⽤とクエリ⽤でモデルを分ける

  41. #ccc_e6 僕とCQRS 定義としてはこれ

  42. #ccc_e6 僕とCQRS 今までこんな感じだったけど

  43. #ccc_e6 僕とCQRS こうやってみると・・・あぁそうか

  44. #ccc_e6 僕とCQRS ひとつのモデルにとらわれることなかったんだ! 分けて考えていいんだ!という気づき ⾔われてみれば「確かに!」なんだけど、⾔われるまで全然その 発想がなかったなぁ。

  45. #ccc_e6 僕とCQRS DB分けても良いわけだし 分けなくてもいいんだよ。

  46. #ccc_e6 僕とCQRS Query側にはDomain Modelを置かない という⼿もある

  47. #ccc_e6 僕とCQRS ドメインモデルがクエリから解放された!!

  48. #ccc_e6 僕とCQRS そしてRead側でSQLの⼒も存分に活かせる!!

  49. #ccc_e6 第2話:僕とCQRS 完

  50. #ccc_e6 第3話:僕とDomain Event

  51. #ccc_e6 僕とDomain Event ところで、コンテキストや集約を切り離したら これまでトランザクションでつないでた情報を どうやって伝えよう? いや、僕は実は複数の集約をトランザクションで囲ってたりする

  52. #ccc_e6 僕とDomain Event ドメインイベントで集約やコンテキストをつなぐ

  53. #ccc_e6 Domain Event? 「何かが実際に起こった」という事実をモデル化

  54. #ccc_e6 Domain Event 「何かが実際に起こった」という事実をモデル化 • CoffeeOrdered • CoffeeBrewed • CoffeeDelivered

  55. #ccc_e6 僕とDomain Event 発⽣したイベントを受け取って情報を更新

  56. #ccc_e6 僕とDomain Event 確かに現実に合ってるなぁ これならコーヒーショップの店員さんと システムの話ができそう

  57. #ccc_e6 僕とDomain Event ドメインイベント使うの良さそう! 使ってみたい!←イマココ

  58. #ccc_e6 第3話:僕とDomain Event 完

  59. #ccc_e6 第4話:僕とEvent Sourcing

  60. #ccc_e6 僕とEvent Sourcing ん?ドメインイベントを使って もう⼀歩踏み込んだパターンがあるのか? イベントソーシング?⾒てみよう!

  61. #ccc_e6 僕とEvent Sourcing 状態⾃体を書き換えるのはステートソーシング 今やってるやり⽅

  62. #ccc_e6 僕とEvent Sourcing それに対して 「イベントの積み重ねによって今の状態がある」 という考え⽅がイベントソーシング 残り3⽸あるね

  63. #ccc_e6 僕とEvent Sourcing • どんな変更をしてきたのかが分かる • リプレイもできる 昨⽇は5⽸残ってたね

  64. #ccc_e6 僕とEvent Sourcing • クエリ困る 残りの本数が多い順に並 べたいな・・・

  65. #ccc_e6 僕とEvent Sourcing w/ CQRS CQRSを適⽤して、クエリのモデルを分ける

  66. #ccc_e6 A Decade of DDD, CQRS, Event Sourcing Greg Young@DDDEU

    2016 https://youtu.be/LDW0QWie21s Picture: https://flic.kr/p/DLfn5i (CC BY-NC-SA 2.0 https://creativecommons.org/licenses/by-nc-sa/2.0/ )
  67. #ccc_e6 A Decade of DDD, CQRS, Event Sourcing こういうことを⾔ってたりする •

    CQRSはEvent SourcingへのStepping-Stone • CQRS/Event Sourcingを全体に適⽤しない • ⾊んな実現⽅法があって良い ESは考え⽅が全然違うから⼀気にそこまでジャンプするの難しい。 だから、CQRSを踏み台にして進むと良い。って感じのことを ⾔ってた。喋るのはやくて何度も聞き直したー。
  68. #ccc_e6 CQRSとEvent Sourcingはセットなの?

  69. #ccc_e6 CQRSとEvent Sourcingはセットなの? 「CQRSとEvent Sourcingは 別々のパターンだけど共⽣関係にある」 というのがGreg Youngの考え 参照: CQRS

    and Event Sourcing http://codebetter.com/gregyoung/2010/02/13/cqrs-and-event- sourcing/ (参照⽇ 2017-11-17)
  70. #ccc_e6 CQRSとEvent Sourcingはセットなの? CQRSのおかげで Event Sourcingは良い感じになる • さっき⾒たね 参照: CQRS

    and Event Sourcing http://codebetter.com/gregyoung/2010/02/13/cqrs-and-event- sourcing/ (参照⽇ 2017-11-17)
  71. #ccc_e6 CQRSとEvent Sourcingはセットなの? Event Sourcingのおかげで CQRSも良い感じになる • 2PC(2 Phase Commit)が不要

    • 何が変更されたのかが分かる 参照: CQRS and Event Sourcing http://codebetter.com/gregyoung/2010/02/13/cqrs-and-event- sourcing/ (参照⽇ 2017-11-17)
  72. #ccc_e6 どゆこと? さっき考えたCQRSはこんな感じ

  73. #ccc_e6 どゆこと? ドメインイベントを使うとこうなる

  74. #ccc_e6 どゆこと? この場合2PCを考える必要があるのと

  75. #ccc_e6 どゆこと? 変更差分を考える必要がある

  76. #ccc_e6 CQRSとEvent Sourcingはセットなの? なるほどね。だから CQRSにはEvent Sourcingが良く合うってことね 発⽣したイベントをストアに登録するだけだから2PC不要だし、 そのイベント⾃体が差分を表してくれてるからね。

  77. #ccc_e6 僕とEvent Sourcing ⾔ってることは分かる 分かるんだけど、まだ僕には早いかな

  78. #ccc_e6 第4話:僕とEvent Sourcing 完

  79. #ccc_e6 第5話:僕とCQRS(その2) ということで、もう⼀度今の⾃分の⽴ち位置を考えてみる

  80. #ccc_e6 僕とCQRS CQRSでクエリモデルを分離したんよね

  81. #ccc_e6 僕とCQRS よく考えたら、これに近いことを、 DDDをやる前からやってる気もするな・・・

  82. #ccc_e6 僕とCQRS よく考えたら、これに近いことを、 DDDをやる前からやってる気もするな・・・ • クエリ⽤のDBを⽤意したり • レポート⽤のテーブルを使ったり • サーチは別のシステムで作ったり

  83. #ccc_e6 僕とCQRS トリガーは様々 • DBに保存するときに頑張ってたり • 定期実⾏のバッチだったり • APIを呼び出してたり

  84. #ccc_e6 僕とCQRS それもいいね 新しいやり⽅が出てきたからって、これまでのやり⽅を否定する 必要はないと思うってことを伝えたくて。

  85. #ccc_e6 僕とCQRS ま、それは置いといてさっき少し出てきたけど やっぱりドメインイベント駆動型って興味ある

  86. #ccc_e6 僕とCQRS こんな感じにできたら今の僕にちょうど良いかな

  87. #ccc_e6 第5話:僕とCQRS(その2) 完

  88. #ccc_e6 第6話: CQRSとKafkaとSpring Boot

  89. #ccc_e6 CQRSとKafkaとSpring Boot これをやりたい

  90. #ccc_e6 Messaging System イベントをハンドリングするための メッセージングシステムが必要

  91. #ccc_e6 Apache Kafka https://kafka.apache.org/

  92. #ccc_e6 Apache Kafka 分散ストリーミングプラットフォーム https://kafka.apache.org/intro

  93. #ccc_e6 Apache Kafka 仕組み https://kafka.apache.org/intro

  94. #ccc_e6 Apache Kafka 仕組み https://kafka.apache.org/intro

  95. #ccc_e6 Spring Boot + Kafka Demo Project https://github.com/bufferings/jjug2017

  96. #ccc_e6 Demo1: Kafka Java Client KafkaのJavaクライアントを使⽤して Producer/Consumerを使ってみる (Spring Boot関係ないです) Special

    Thanks: Apache KafkaのQuickstartのサンプルを、JavaのClient APIで書き 直してみた – CLOVER http://d.hatena.ne.jp/Kazuhira/20170306/1488814266
  97. #ccc_e6 Demo2: Spring Boot + Kafka Spring BootとSpring Kafkaを使⽤して Producer/Consumerを使ってみる

  98. #ccc_e6 Demo3: Spring BootとKafkaでCQRS Command/Processor/QueryでCQRS的に動かして みる

  99. #ccc_e6 第6話: CQRSとKafkaとSpring Boot 完

  100. #ccc_e6 まとめ

  101. #ccc_e6 まとめ • 第1話:僕とDDD • 第2話:僕とCQRS • 第3話:僕とDomain Event •

    第4話:僕とEvent Sourcing • 第5話:僕とCQRS(その2) • 第6話:Spring BootとKafkaでCQRS
  102. #ccc_e6 まとめ 今の僕の状況 これを実現させるための勉強をしていこうと思ってる。

  103. #ccc_e6 注意点 全てをCQRSにしない • CQRSやESは複雑さを持ち込んでしまう • CRUDは⾊んなことをシンプルにしてくれる • 本当に必要で有効な場所だけに使うといい そのために⾊々と⼩さく切り離しておくのが役に⽴つね。

  104. #ccc_e6 この後やってみたいこと • Functional Programming • Reactive Programming • Event

    Sourcing • Kafka Streams • Kafka Connect
  105. #ccc_e6 この後やってみたいこと • Functional Programming • Reactive Programming • Event

    Sourcing • Kafka Streams • Kafka Connect の中のどれか1個 他のは勉強会とかに聞きに⾏きますので誰か教えて!!
  106. #ccc_e6 最後に 以上が、僕の試⾏錯誤のお話でした。

  107. #ccc_e6 最後に 何かもし「いいな」って思うことがあったなら ご褒美に、あなたのお話を聞かせてください!

  108. #ccc_e6 最後に 懇親会でもいいし、ツイッターでもいいし、 次のJJUG CCCで発表してくれるのでも いいと思います! ありがとうございました!

  109. #ccc_e6 Reference CQRS, Task Based UIs, Event Sourcing agh! •

    http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/ CQRS and Event Sourcing • http://codebetter.com/gregyoung/2010/02/13/cqrs-and-event-sourcing/ Bliki: CQRS • https://martinfowler.com/bliki/CQRS.html Bliki: ReportingDatabase • https://martinfowler.com/bliki/ReportingDatabase.html CQRS Documents by Greg Young • https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf
  110. #ccc_e6 Reference Greg Young — A Decade of DDD, CQRS,

    Event Sourcing • https://youtu.be/LDW0QWie21s CQRSに取り組むべき時期、理由、⽅法(Sebastian Daschner) • https://youtu.be/ajASbq5pzss エリック・エヴァンスのドメイン駆動設計 • https://books.rakuten.co.jp/rb/11146351/ 実践ドメイン駆動設計 • https://books.rakuten.co.jp/rb/13138730/ 現場で役⽴つシステム設計の原則 • https://books.rakuten.co.jp/rb/15017530/
  111. #ccc_e6 Reference Apache Kafka • https://kafka.apache.org/ Apache Kafkaに⼊⾨した | SOTA

    • http://deeeet.com/writing/2015/09/01/apache-kafka/ Event sourcing, CQRS, stream processing and Apache Kafka: What’s the connection? • https://www.confluent.io/blog/event-sourcing-cqrs-stream-processing-apache-kafka-whats- connection/ Building a Microservices Ecosystem with Kafka Streams and KSQL • https://www.confluent.io/blog/building-a-microservices-ecosystem-with-kafka-streams-and- ksql/ Building Event-driven Microservices Using CQRS and Serverless • http://www.kennybastani.com/2017/01/building-event-driven-microservices.html
  112. #ccc_e6 Reference Apache KafkaのQuickstartのサンプルを、JavaのClient APIで書き直してみた - CLOVER • http://d.hatena.ne.jp/Kazuhira/20170306/1488814266 Cacoo

    • https://cacoo.com/ja
  113. None