Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

小さなサービスも契約する時代

2,866 views

Published on

コンシューマ駆動契約についてのお話。
Osaka Venture Today Meetup #4 - 開発生産性アップの秘訣の登壇資料です。
https://kansai-venture.connpass.com/event/97256/

Published in: Technology
  • Be the first to comment

小さなサービスも契約する時代

  1. 1. 小さなサービスも 契約する時代 マイクロサービスのテストをすばやく回し デプロイを安全にやるよい方法 サイボウズ 西日本開発部 大阪オフィス 三苫 亮 Osaka Venture Today Meetup #4 2018/10/26
  2. 2. 自己紹介 • 三苫 亮 (みとま りょう) • @mitomasan • サイボウズ西日本開発部 • kintone開発チーム Yakumoプロジェクト • サーバーサイドエンジニア • 2015年9月中途入社 • 週2日出社、週3日在宅
  3. 3. 目次 • 今日のゴール • マイクロサービスとは • テストにおける課題 • どうすればいいのか? • コンシューマ駆動契約 • サイボウズでの事例 • まとめ
  4. 4. 今日のゴール • コンシューマ駆動契約の概念を知る • サイボウズの事例を聞いて やってみようという気になる
  5. 5. 想定聴衆 • 自動テストを知っている • JUnit とか RSpec とか • Selenium による E2E テストとか • マイクロサービスアーキテクチャについて知っている • 概要レベル
  6. 6. コンシューマ駆動契約とは マイクロサービスアーキテクチャで構築されたシステムで各サービスを任意の タイミングでリリースできるようにすると、全体が結合された環境で行うテスト は非常に高価になりこの方法ですべてのユースケースをテストすることはできな くなる。 各サービスは自分がどのサービスから呼び出されているか把握することが困難 になり、互換性を壊す変更をリリース前に検出することが難しくなる。 コンシューマ駆動契約とはサービスの利用側・提供側で (状態, 入力, 出力) の組 を契約と定義し、サービス利用側(コンシューマ)が契約を結ぶことを責務とし、そ の契約を壊していないことを利用側・提供側双方でテストすることで結合環境で のテストの代替として上記の問題を解決するものである。 三苫の理解より長すぎるゾ!
  7. 7. コンシューマ駆動契約とは マイクロサービスアーキテクチャで構築されたシステムで各サービスを任意の タイミングでリリースできるようにすると、全体が結合された環境で行うテスト は非常に高価になりこの方法ですべてのユースケースをテストすることはできな くなる。 各サービスは自分がどのサービスから呼び出されているか把握することが困難 になり、互換性を壊す変更をリリース前に検出することが難しくなる。 コンシューマ駆動契約とはサービスの利用側・提供側で (状態, 入力, 出力) の組 を契約と定義し、サービス利用側(コンシューマ)が契約を結ぶことを責務とし、そ の契約を壊していないことを利用側・提供側双方でテストすることで結合環境で のテストの代替として上記の問題を解決するものである。 三苫の理解より課題を説明してから解決を説明します 課 題 解 決
  8. 8. マイクロサービスとは
  9. 9. マイクロサービスとは 連携して動作する独自のライフサイクルを備えた粒度の細かい サービスを促進する、分散システムへの取り組み O’REILLY マイクロサービスアーキテクチャより
  10. 10. モノリス システム ロードバランサ データベース サービス
  11. 11. マイクロサービス システム ロードバランサ データベースA サービスA データベースB サービスB データベースC サービスC
  12. 12. 連携して動作する システム ロードバランサ データベースA サービスA データベースB サービスB データベースC サービスC 全体で一つの システムなんだね
  13. 13. システム サービス単位 独自のライフサイクルを備えた ロードバランサ データベースA サービスA データベースB サービスB データベースC サービスC 開発・テスト・リ リースはサービス 単位なんだね
  14. 14. システム 粒度の細かいサービスを促進する ロードバランサ データベースA サービスA データベースB サービスB データベースC サービスC この状態から モノリス作る気 にならんわ
  15. 15. 分散システムへの取り組み システム ロードバランサ データベースA サービスA データベースB サービスB データベースC サービスC これはもはや 完全に 分散システム と言えよう…
  16. 16. マイクロサービスの良いところ その1 • 技術的異質性 • サービスごとに別の技術を使える • 回復性 • サービスの一つが障害を起こしてもそのほかは稼働し続ける • スケーリング • サービス単位でスケールアップ・スケールアウトできる • デプロイ容易性 • サービス単位でリリースできるので変更差分を小さくできる
  17. 17. マイクロサービスの良いところ その2 • 組織面の一致 • チームとサービスを一致させることで チーム間の折衝が減らせる • 合成可能性 • サービスが単機能であるほど再利用しやすい • 交換可能にするための最適化 • レガシーになっても、リライトできる規模
  18. 18. テストにおける課題
  19. 19. 全体を結合したテストが大変 システム ロードバランサ データベースA サービスA データベースB サービスB データベースC サービスC BのテストするのにAとCも セットアップするの? 面倒だなぁ…。 全部起動するにもマシンス ペックがキビシイよ。
  20. 20. どのバージョンでテストする? システム ロードバランサ データベースA サービスA v1.1 データベースB サービスB v1.3 データベースC サービスC v1.0 新しいBのテストしたいけ どAとCはどのバージョン想 定してテスト書いたらいい のよ? 来週にはv1.1に あげるで~
  21. 21. 誰がこのAPIを利用してる? システム データベースA サービスA データベースB サービスB データベースC サービスC サービスAのAPIを変更した けど、知らない間にサービ スCに使われていて、変更 連絡が漏れた状態で本番投 入して障害起こしました。 実は僕も使って ました~!! APIに破壊的変更 入れるから オッケー👌 呼び出し修正したよ
  22. 22. コンシューマ駆動契約とは マイクロサービスアーキテクチャで構築されたシステムで各サービスを任意の タイミングでリリースできるようにすると、全体が結合された環境で行うテスト は非常に高価になりこの方法ですべてのユースケースをテストすることはできな くなる。 各サービスは自分がどのサービスから呼び出されているか把握することが困難 になり、互換性を壊す変更をリリース前に検出することが難しくなる。 コンシューマ駆動契約とはサービスの利用側・提供側で (状態, 入力, 出力) の組 を契約と定義し、サービス利用側(コンシューマ)が契約を結ぶことを責務とし、そ の契約を壊していないことを利用側・提供側双方でテストすることで結合環境で のテストの代替として上記の問題を解決するものである。 三苫の理解よりこれが課題です。 課 題
  23. 23. どうすればいいのか?
  24. 24. 歯を食いしばってやろう • こういうのは愚直にやるのが一番? • サービス間の関連は多対多関連 • 負荷が指数的に増加する可能性 • 指数的なものとそのまま戦う人は時間に殺される
  25. 25. クライアントライブラリは 自動生成の時代! • クライアントライブラリを Swagger や Open API Generator で自動生成して提供すれば 形式不正なAPI呼び出しはなくせるのでは? • そういう話ではない。 • 互換性の崩れた古いクライアントライブラリを 意図せず使い続けられたら結局困る。
  26. 26. モノリポジトリの採用 • 全部のコードを一つのリポジトリに入れることで 一つのリビジョンでは全体の整合性が 担保できるのでは? • マイクロサービスではモノリポジトリを採用してもリ リースサイクルは別になるため、これも解決にはなら ない
  27. 27. 不十分なテストで本番に突っ込んで 異常検知したら取り下げる • これはこれでアリ (^_-)-☆ • 程度の差はあれ十分なテスト(≒障害の芽をすべて摘 む)とは幻想なので、大なり小なりすべてのチームが 採用している方針 • ここに至るまでどこまで手を尽くせるかという話
  28. 28. コンシューマ駆動契約
  29. 29. 私たちは何を知りたい? • 提供しているAPIが他のサービスからの呼び出しを壊し ていない事を確認したい • 各サービスの最新版だけではなくて本番環境に現在リ リースされているバージョンに対しても互換性を壊し ていない事を確認したい
  30. 30. APIの通信をテストするための情報 • サービスの状態(State) • 入力(Request) • 出力(Response) サービスA サービスB State : ID=12345でuser=三苫が登録されている Request : GET /v1/users/12345 Response : {“name”: “三苫 亮”}
  31. 31. APIの通信をテストするための情報 • サービスの状態(State) • 入力(Request) • 出力(Response) サービスA サービスB State : ID=12345でuser=三苫が登録されている Request : GET /v1/users/12345 Response : {“name”: “三苫 亮”} これを契約と定義する
  32. 32. 利用側モック 契約をもとに独立してテストできる サービスA サービスB 契約 契約をもとにAPIを呼び出した レスポンスを検証する 契約をもとにAPIの呼びだす リクエストを検証する 提供側モック 契約
  33. 33. 契約にメタ情報を付与してDB化してみる 利用者 : サービスB (version:1.0.0) 提供者 : サービスA (version:2.0.0) State : ID=12345でuser=三苫が登録されている Request : GET /v1/users/12345 Response : {“name”: “三苫 亮”} 契約 契約 契約
  34. 34. 利用側モック 提供側が守るべき契約をDBに 問い合わせできる サービスA サービスB 提供側モック 契約 契約 契約 守ってほしい契約を利用側が作ってDBに登録 守るべき契約を提供側がDBから読み込む
  35. 35. 利用側モック 提供側が守るべき契約をDBに 問い合わせできる サービスA サービスB 提供側モック 契約 契約 契約 守ってほしい契約を利用側が作ってDBに登録 守るべき契約を提供側がDBから読み込む 本番環境のバージョンを指 定すれば本番環境での契約 を壊していないかがわかる
  36. 36. コンシューマ駆動契約とは マイクロサービスアーキテクチャで構築されたシステムで各サービスを任意の タイミングでリリースできるようにすると、全体が結合された環境で行うテスト は非常に高価になりこの方法ですべてのユースケースをテストすることはできな くなる。 各サービスは自分がどのサービスから呼び出されているか把握することが困難 になり、互換性を壊す変更をリリース前に検出することが難しくなる。 コンシューマ駆動契約とはサービスの利用側・提供側で (状態, 入力, 出力) の組 を契約と定義し、サービス利用側(コンシューマ)が契約を結ぶことを責務とし、そ の契約を壊していないことを利用側・提供側双方でテストすることで結合環境で のテストの代替として上記の問題を解決するものである。 三苫の理解よりこれで解決! 解 決
  37. 37. ここで用語を整理 • APIの提供側→プロバイダ • APIの利用側→コンシューマ • APIの仕様の合意→契約 • 利用側が起点となって提供側と契約する →コンシューマ駆動契約 • コンシューマ駆動契約 →Consumer Driven Contract →CDC
  38. 38. CDCは何を解決しないか • 契約していないサービスの互換性の保証 • 契約は全サービスが行わないとあまり意味がない • 契約が壊れた時のチーム間コミュニケーション • 問題を検出するまでが範囲 • APIの実際の動作の保証 • インターフェイスが壊れていない事だけ保証する • サービス間の実際の疎通 • 全体の結合テストを価値の高いユースケースに 絞って作る必要はある • テストピラミッドの考え方
  39. 39. サイボウズの事例
  40. 40. kintone • 業務改善プラットフォーム • 業務アプリを簡単に作る • ストック&フローの データを貯めていける
  41. 41. Yakumoプロジェクト • kintone を自社DCからAWSに移行するプロジェクト • US向け • 詳しくはこちら↓ • https://www.slideshare.net/teppeis/kintone-awsdvopsqa-111906067 • kintone は元からマイクロサービス的な構成 • 自作ミドルウェアが複数あり HTTPリクエストを投げている • 自作ミドルウェアをAWSに最適化したものに再実装する 過程で全体結合したテストを行うのが難しくなり コンシューマ駆動契約を実践することに
  42. 42. サービスの依存関係 契約を図示したもの
  43. 43. コンシューマ駆動契約を実現するツール • Pact • https://docs.pact.io/ • もともとは Ruby で書かれた コンシューマ駆動契約を実現するためのツール • 契約を JSON 形式の Pact ファイルで表現する • 特定の言語依存がない • 今では多くの言語で Pact ファイルを用いた CDC テストができる • Yakumo では Java, kotlin, Go でテストを書いている
  44. 44. Pact 利用側モック この範囲 サービスA サービスB 提供側モック 契約 契約 契約 守ってほしい契約を利用側が作ってDBに登録 守るべき契約を提供側がDBから読み込む
  45. 45. xUnit コンシューマ側 • プロバイダーにアクセスするクライアントの 単体テストを Pact を使って実装 • Pactでモックサーバーを立ち上げて単体テストする テスト対象の クライアント Pactによる モックサーバー
  46. 46. xUnit プロバイダ側 • プロバイダ側はサービスを実際に立ち上げ DBは本物・依存サービスはモックを使って実装 • サービスの状態(State)をキーにDBやモックを セットアップして入出力を検証 Pactによる モッククライアント テスト対象の サービス DB 依存するサービス のモック
  47. 47. プロバイダ側のテストは誰が書く? • 今のところコンシューマ側のテストを書いた人が プロバイダ側のテストも対応する • 使いまわせる State が増えると プロバイダ側の対応は不要になってくる
  48. 48. 課題 • 今は契約のJSON(Pact file)はモノリポジトリに ファイルとして置いてあるだけ • 契約をDB(Pact Broker)においてバージョンを指定して テストできるようにするのはこれから • サービスの状態(State)を表す語彙が チームで標準化されていない • “normal state” とか “has one queue” とか曖昧な 言葉でしか定義されていない
  49. 49. まとめ • コンシューマ駆動契約を導入することで サービスを結合せずに確認できる範囲を 増やすことができる • 万能ではないし結合して実施するテストが 全く不要というわけでもない • サイボウズも Yakumo というプロジェクトで Pact を活用してやっていってるゾ!
  50. 50. 参考 • Pact • https://docs.pact.io/ • pact-jvmではじめるコンシューマー駆動契約 • https://www.slideshare.net/setoazusa/pact-for-jvm • 運用中のサービス間の堅牢性をあげるために Pact導入を試みた話 • https://developers.freee.co.jp/entry/introduction-of-pact • 実践 Pact:マイクロサービス時代のテストツール • https://techlife.cookpad.com/entry/2016/06/28/164247
  51. 51. おしまい Yakumo やってやれないことはない メ ン バ ー 募 集 中

×