【セッションレポート】Developers.IO 2015「クラスメソッドのAWSドッグフーディング」#cmdevio2015C

Developer Day - Developers.IO 2015

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

よく訓練されたアップル信者、都元です。先週末、3/27(金)及び3/29(日)の2daysで、Developers.IO 2015という弊社主催イベントを実施しました。ご来場頂きました方々にあらためてお礼申し上げます。

cmdevio2015-top

さて、3/29(日)の Developer Day のC-1のコマにおいて、2コマぶち抜きの濃厚なセッションを実施しました。一応事前予告として書いた情報はこちらです。

13:00 - 14:45 C-1『クラスメソッドのAWSドッグフーディング』 (by 都元ダイスケ)

予告通り、内容は多岐にわたり、とあるプロジェクトで利用している様々な技術をご紹介しました。

スライド

当初45分×2コマで90分と考えていましたが、スキマに15分という休み時間を発見し、結果的に105分。そしてスライドは105枚+α、という濃密なセッションでした。

アジェンダ項目ごとにざっと振り返り

このセッションを通じて「AWSの哲学・推奨に従い、AWSに最適化し、AWSに寄り添ったシステム作り」の具体的な事例と手法、そしてTipsをご紹介しました。AWSの機能をフル活用することによって実現できた、私が理想的だと考えるシステムの特徴は以下のとおりです。

完全AWSネイティブ

  • AWSの哲学・推奨に従う。AWSに寄り添う。
  • 全てのサーバはMulti-AZのAutoscaling構成でデプロイする。これにより、可用性と拡張性を同時に手に入れる。
  • Multi-AZには「Webパターン」と「Workerパターン」がある。アプリケーションはこのどちらかにデプロイ。ここから外れたくなったらAWSの哲学的に何かがおかしくなりはじめている。
  • これらのパターンはElastic Beanstalkによってホストする。
  • ジョブスケジューラのMulti-AZは鬼門であった。Brianでそれを解決する。
  • 一部の例外を除き、CloudFormationテンプレート外でAWSリソースを定義しない。

Java 8 + Spring Framework

これは「私が理想的だと考えるシステムの特徴」という訳ではありませんが、これらの言語・フレームワークを使った場合、どのような構成が理想的になるのか、を考えてみたセクションです。

  • プロジェクトは最低限、ドメインモデルとWebアプリケーションで分ける。ドメインモデルのプロジェクトには、Web系のフレームワークへの依存は無いはず。という足枷が、ドメインモデルの純化にいい働きをすると思う。
  • Spring DataとDDDが相性良いです。
  • Spring BootとDockerが相性良いです。
  • Spring BatchとSQSが相性良いです。

Single Command Deployとシステムポータビリティ

  • リポジトリからコードをチェックアウトし、 必要に応じて環境固有の設定をした後、 コマンド1つで起動・デプロイができるべき。
  • バージョン管理(構成管理)の対象は、アプリケーションコードだけではなく、インフラ定義も含まれる。 所謂、Infrastructure as Codeの話。これにより、昔の状態のコードが常に動かせる。
  • プロジェクトのビルドスクリプトにはGradleを採用。
    • CloudFormationのキックは、gradle-aws-pluginを活用する。
    • DBのマイグレーションにはFlywayを活用する。
  • Infrastructure as Codeにより大部分のインフラ構築が自動化(Automated)できるが、様々な事情により一部自動化が不可能・困難な箇所もありうる。その場合は、ポエム(文書)として再現性のある手順を明記(Documetnted)する。すると、全ての操作がAutomated + Documetntedとなり、これをFull Describedと呼ぼう。システムはFull Describedであるべきだ。 *1
  • 僅かなDocumentedな操作(環境固有の設定値の書き込み等)と、たった1つのコマンド実行で、システムのローカル起動、及びAWS環境へのデプロイができるべき。これを Single Command Deploy と呼ぶ。
  • 以上の体制で自動化したシステムは、
    • 1つのAWSアカウント上に複数のシステムが立ち上げられるべきである。
    • あらゆるAWSアカウント上にシステムが立ち上げられるべきである。
    • あらゆるリージョンに、システムが立ち上げられるべきである。

    と思っています。AWSアカウントIDをハードコーディングしたり、特定アカウントからしか見えないAMIに依存しない。

APIファースト

  • 全ての提供機能にAPIを用意し、静的アセットとしてのUIがAPIを叩く構成にする。(要するにAWSの真似)
  • APIの本文フォーマットは基本的にJSONで、HATEOASを使うことにより、ヒューマンフレンドリーなリンクを提供。
  • HALのembedを用いることで、1画面あたりのAPIコール数を削減できる。(必ず 1 screen = 1 API call にはできないかも?)
  • 更新APIの設計は難しい。都度都度熟考。REST without POSTという悟りの世界も場合によっては有効。
  • APIドキュメントはSwaggerで自動化できる。
  • Go言語を使ってaurlというOAuth2トークン管理機能付きHTTPクライアントを作ってみたら、みんなが使ってくれた。

まとめ

結局、105分ほぼぶっ続けで私の好きな話をハイペースでお話させていただき、非常に楽しかったんですが、聞いてたみなさん大変でしたよね。お疲れ様でした。何らかのヒントを持ち帰って頂いていれば、幸いです。

個別の要素技術(Swagger, HATEOAS等)やその組み合わせ(Spring BootとDocker、DockerとElastic Beanstalk等)については、それぞれ別途、詳しいブログを書いていこうと思っています。乞うご期待。

脚注

  1. そして可能ならばなるべくDocumentedではなくAutomatedの方に寄せたい。ポエムを書きたくなければ自動化するのだ。