How Microservices are linked at Cookpad 参加レポート #microsvc

イベントページ

connpass.com

スライド

speakerdeck.com

今回離さないこと

  • 包括的な話

今回話すこと

  • 事例をどんどん話す

どんなサービスから構成されているか

  • 粒度も含め
  • 社内で明確なルールが有るわけではないが以下の3つ。
    • ユーザーサービス
    • ビューサービス
    • 共通基盤
  • 1つの事業ドメインだとあまり価値が無いのかもしれない

ユーザーサービス

  • 「料理を通じて=レシピがあれば良い」というわけでない
    • 料理教室とか
    • 特売情報とか
    • 産地直送便を結ぶサービスとか
  • それに特化した独立したサービスを作る
  • ドメインは隣接しているので、他のドメインを使ったりする
  • よくある機能は共通基盤を活用
  • 大事なことは、逆向きになっても良いようにすること

ビューサービス

  • Backend for frontendsに近い
  • バイスごとに専用ビューを作ることはほぼない
  • OEM版で使われたりする

共通基盤サービス

  • UIもあればAPIのみのものもある

連結方法

  • RESTful Hypermedia API
  • クックパッドのモデルは非常に多い
  • 特定の高負荷なモデルが有るわけではない
    • パフォーマンスの最適化よりも柔軟性重視

Garage

Garage Client

  • xxx-clientが無限増殖しないで済む
  • 特定のサービスを使う時の学習コストがかからない

サービス間通信のコスト軽減/耐障害性

Expeditor

  • 基本的な非同期実行や条件付きの非同期実行、サーキットブレイクなどは搭載されている
  • RESTであるユーザーの情報を複数のサービスから集めたいとかに使える

互換性の担保について

  • サービス間連携をどうテストするか
  • Rubyの会社は型を意識することがあまりない
  • 動くものに対してなんとかしようと考えることが多い

CDC Testing

Pact

  • クライアント側がテストを書いてCIで回す
  • Pactファイルを生成してBlocker側に渡す
  • 自身がそれを実装されているか試す
  • WEB Mockにほぼ近い
  • 後は普通にテストを書くだけ
  • テストした後の生成物は中身が出てくる
  • API側は必要な前処理を用意することで、後はPact側が自動的にテストしてくれる

Rack::VCR

  • 以前導入していた
  • クライアント側が意識しなくてもスタブを用意してくれる
  • API側のビルドが高頻度の場合、クライアント側の検知前にリリースされうる

エラーの追跡

Sentry

  • サービスごとのエラーを集約管理している
  • ただし、サービス間のひも付けはできない
  • リクエストIDを採番する
    • Railsはデフォルトで採番している
  • GarageClientがリクエストIDを次のリクエスト先に伝搬すれば良い
  • Sentryでエラーを検索できるようにしている

Docker

  • 巨大なRailsアプリ以外はほとんどDockerになっている
  • プロダクション環境もDocker
  • 環境依存地のみ環境変数として注入
  • アプリケーションリポジトリに入っている
    • poppetではモジュール管理が複雑
      • インフラ関係者しかできない
  • 手元でミドルウェアを増やすとかもできるように
  • 開発者の自由度を上げる

ビルドパイプライン

  • masterにマージ
  • CIでテスト
  • Dockerのイメージ作成
    • assetなども作っちゃう
  • 自動でデプロイ
  • Chatでデプロイを実行する

Hako

  • デプロイ管理
  • 以前はインフラメンバや基盤メンバが細かく設定を書いていた
  • アプリケーションごとの設定はYAMLで管理

etcenv/etcvault

  • etcdで設定値を管理
  • 特定のカギを持っているインスタンスでしか復号できない

Chat ops

  • Hubotでdeploy
  • 裏ではRundeckで管理
  • デプロイコマンドはアプリケーションに特化しているのでRundexkで管理
  • 基本、Hubotで言えばdeployできる形で統一

バッチジョブ

kuroko2

  • Jobのワークフローの管理
  • 全サービスのJobを一括管理
  • フックして別サービスをKickする
  • サービスの最新のDockerイメージを実行するように
    • 以前だと、ワーカーでサービスごとの構成管理をしていたので、Kuroko用とワーカー用のアプリケーションで管理を別々にしなくちゃいけなかった

組織的な話

技術領域課題共有会

  • 名前とは違い、ざっくばらんな話し合い
    • こういうコマンド毎回打つのだるい
    • ドキュメントどこー
    • 技術的にこのやり方は…
    • こういうのがあったら使う?
    • こういうのまだ使ってる?
      • メンテコストが高くならないように
  • 感覚値がチームによって違うことが把握できる

技術基盤担当

  • 技術基盤に余力があるか、経験のある人がいるかどうかがチームによってバラバラになりがち
  • サービスが大きくなると、どういう基盤があるか分からなくなりがち
  • 各チームに専任の技術基盤担当がいるようにする
    • MTGに参加したり
    • カジュアルな相談に答えたり
    • 必要に応じてガッツリ入ったり