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

Spring BootとKafkaでCQRS

Spring BootとKafkaでCQRS

JJUG CCC 2017 FALL

979f8815a9d4604d87f54b8394c503bd?s=128

Mitsuyuki Shiiba

November 18, 2017
Tweet

More Decks by Mitsuyuki Shiiba

Other Decks in Programming

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