狠狠撸

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

More Related Content

小さなサービスも契约する时代