AWS Summit 2017_2017-06-02

2017/06/02は以下に参加

  • 全部教えます!サーバレスアプリのアンチパターンとチューニング
  • サーバレスで王道Webフレームワークを使う方法
  • Serverless時代のテスト戦略 – Testable Lambda
  • AWS SAMで始めるサーバレスアプリケーション開発
  • サーバレスアプリケーションのためのCI/CDパイプライン構築

以下,読みにくいので時間あったら整形

全部教えます!サーバレスアプリのアンチパターンとチューニング

13:20-
@Keisuke69

対象

  • AWS Lambda およびサーバレス自体は知っている
  • 実際に自分で実装したことがある
  • これから自分で実装しようとしている

速度が出ないアンチパターン

プログラムの問題

  • ロジックそのものが遅い
    • 各言語のベストプラクティス、最適化手法はそのまま当てはまる
    • プラットフォーム側ではどうしようもない

コンピューティングリソース不足

  • メモリ設定
    • 設定値はメモリだが、コンピューティングリソースも合わせて上がる
    • コストを気にし勝ちになるが、処理時間が減るため、結果的には変わらないケースも
    • 少しずつ調整し、変更しても性能が変わらない値が最適化

コールドスタート

  • 処理流れ
    • (ENIの作成)
      • VPCを利用する場合だけ
      • 10-30 secかかる
      • Durationには含まれない
    • コンテナの作成
    • デプロイパッケージのロード
    • デプロイパッケージの展開
      • 指定された欄t内務
      • S3からDL,展開
      • Durationには含まれない
    • ランタイム起動・初期化
      • 各ランタイムの初期化
      • グローバルスコープの処理もこのタイミング
        • ただしタイムアウトあり
      • Durationには含まれない
    • 関数/メソッドの実行
      • ハンドラーで指定した関数/メソッドの実行
      • DUrationの値はここの実行時間(課金対象)
  • 上記をすべて実行するのがコールドスタート
    • ENIからランタイムの初期化までを再利用するのがウォームスタート
  • コールドスタートが起きる条件
    • 利用可能なコンテナがない場合
    • 利用可能な数以上に同時処理すべきリクエストが来た
    • コード、設定を変更した
    • つまり、安定的にリクエストが来ているならばコールドスタートはほとんど発生しない
  • コールドスタート
    • 0にすることは不可能
    • コールドスタートを全く許容できない場合はAWS Lambdaは正解でない

コールドスタートを速くする

  • コンピューティングリソースを増やす
    • 初期化処理自体が速くなる
  • ランタイムを変える
    • JVMの起動は遅い
    • ただし、一度あたたまるとコンパイル言語のほうが速い
  • パッケージサイズを小さくする
    • サイズが小さいと、コードロード、展開を減らす
    • 不要なコードは減らす
    • 依存関係は減らす
      • 特にJava
        • JavaだとProGuardなどのコード最適化ツールを使って減らすなど
  • VPCは必要でない限り使用しない
  • 同時実行が必要な箇所やコールドスタートが許容できない箇所は利用しない
    • VPCないのリソースとの通信が必要なのであれば非同期
    • RDBMSのデータ同期 -> DynamoDB Streamsにする
  • Javaの場合は以下も検討
    • POJOではなくバイトストリーム
      • 内部で利用するJSONシリアライゼーションライブラリは多少時間がかかる
        • jackson-jr
  • 初期処理をハンドラの外に書くとコールドスタートが遅くなるので遅延ロードを行なう

アーキテクチャの問題

  • 同期でInvokeすると同時実行数の制限に引っかかりがち
    • 非同期呼び出しの場合、許可された同時実行数内で順次処理をしバーストも許容されている
    • 同時呼び出しの場合は、許可された同時実行数を越えた時点でエラーが返される
      • 非同期の場合はリトライされる
  • できるだけ非同期でInvoke
    • 本当にレスポンスが必要か
    • API Gatewayの組み合わせの場合、PUT系の処理をAWS Lambdaで直接処理するのではなく、サービスプロキシとして構成し、Amazon SQS, Kinesisに流すなどする
  • APIGatewayのバックエンドに呼べる
    • Kinesisとか
  • Think Parallel
    • AWS Lambdaを最大限活かすには、以下に並列処理を行なうか
  • 1つあたりのイベントを小さくして、同時に並列で動かせるアーキテクチャへ
    • 1回のInvokeでループではなく、ループ回数分Lambdaファンクションを非同期Invokeする
    • 長時間実行のLambdaファンクションも減り、同時実行数の制限にも引っかからない

同時実行数

  • 秒間リクエスト × 関数の実行時間
  • ストリームベース
    • シャードの数 = 同時実行数
    • トラフィックに応じてシャードを増やす必要がある
  • 制限緩和
    • 実際にThrottleされているかどうか確認
    • もしくはサービスロンチは時間的余裕をもって相談

アンチパターン

  • Lambda + RDBMSはアンチパターン
    • コネクション数の問題
    • VPCコールドスタート問題
  • ベストプラクティス

    • Amazon Dynamo DB
    • RDBMSとの連携が必要な場合は DynamoDBStreamsの非同期
  • IP固定したがり問題

    • API gatewayやAWS Lambdaから別システムや外部APIへの接続
    • 署名や証明書で担保すべき
    • VPCを利用すればNATインスタンスでできなくもないが、
      • コールドスタート
      • NATインスタンスの可用性、信頼性、スケーラビリティ
  • サーバレスに夢見がち

    • サーバ管理不要だが運用は日宇町
    • コスト効率が高いが、リクエスト数が多いとそれなりの費用
    • インフラ費用だけでなく、トータルコスト
    • 複雑なことをやろうとすると、設計・開発コストが上がる
    • Not Monitorless
      • CloudWatchのメトリクスを利用(Errors, Throttles)
      • CloudWatchのカスタムメトリクス
      • CloudWatch Logsへのログ出力とアラーム設定
  • 通常の他のサービスと同様に障害発生

    • リトライ
    • DLQの活用
  • 冪等性はお客様のコードで確保する

    • AWS Lambdaで保証するのは最低1回実行することであるが、1回しか実行しないことではない
    • 同一イベントで同一Function 2回も起こりうる

サーバレスで王道Webフレームワークを使う方法

14:20-
@akitsukada

セッションについて

解決したい課題

  • AWS Lambda , API Gatewayでバックエンドを全部作れるか
  • Lambdaで大きいWebアプリを開発するの大変そう
    • 多くのLambdaファンクションをどう管理するか
    • デプロイや運用のベストプラクティス
  • いつものフレームワーク

対象

  • 一般的なWebフレームワークをつかったアプリケーション開発のけいけんあり
  • Lambda, APiGatewayは知っているが、WebアプリはEC2上に構築する

github/awslabs

Express.js

How to Get Started

awslabsのexampleを走らせる

  • git cloneしてsample
  • npm install && npm run start
    • ローカル開発では Node.js >= 4.0
  • npm run config でアカウントの設定ができます

既存プロジェクトのマイグレーション

  • 既存プロジェクトのメインファイル名 app.jsでない場合は lambda.jsの修正が必要
  • ソースコードをトップ以外のディレクトリに配置している場合、cloudformation.yamlの修正が必要
  • ローカルのテストは npm run local
    • api-gateway-event.jsonのデータがeventとして渡される
  • API Gatewayの構成を変更したい場合は、simple-proxy-api.yamlを、

How It Works

aws-serverless-expressの振る舞い

REST full -> GET /users -> application/json
HTML -> GET / -> text/html

Lambda Integration Proxy は、Lambda側でレスポンスタイムを選べる
Binary media : / で画像ファイルを返却できる

Spring Framework

How to Get Started

awslabsのsample(pet-store)

  • mvn package
  • CloudFormation の artifact

既存プロジェクトのマイグレーション

  • 依存関係の設定 (pom.xml)
  • LambdaHandlerを作成する

How It Works

  • 各自のSpringアプリの実装すればよい
    • Spring Framworkはラッパーライブラリ

AWS CodeStar

まとめ

  • github/awslabs
  • Express.jsとSpring Framewokで従来通りの開発が可能
  • awslabsのsampleww走らせるのも既存プロジェクトをマイグレーションするのも非常にかんたん
  • AWS CodeStarは CI/CDパイプラインまで自動構築

Serverless時代のテスト戦略 – Testable Lambda

@t_wada

現状確認

  • AWS Lambdaの自動テストに対するベストプラクティスはまだない
  • 自動テストを書いて振る舞いが変わっていないことを確かめながら新しいコーディングスタイルに移行したい
  • 手順書による
  • SAMで効率化できる
    • SAMでデプロイ用バケット準備
  • デプロイなしでローカルでテストしたい

テスト自動化ピラミッドとアンチパターン

  • テスト自動化ピラミッド
    • 手動テストは少ない
    • 自動化Unitテストが多い
  • アイスクリームアンチパターン
    • 手動テストが多い
    • Unitテストは少ない

テスタビリティをこじ開ける

  • テストがないコードはレガシーコード
  • リファクタリングする前にUnitTestを書くのはときに不可能で無意味
    • 粗い粒度のテストを使いこなす
  • Fake Object
  • 本番コードに分岐をかかない
    • seam(接合部)をつくる
    • 関数呼び出しの際に環境情報を渡す
  • 2secで自動テストが出来るようになった

サイズとピラミッドとループ

  • カバレッジを測定
    • ファイルレベルでカバレッジを確認する
  • テストサイズの考え方
    • "Test Sizes" at Google
    • mediumテストは、localstack
    • 例外系テストは smallテスト(localstackを使わない)
    • テストしていないコードは動かない
    • largeテスト
    • ブランチごとに違う環境を用意したほうが良い

ここから先

  • アーキテクチャをきれいにしていく
    • The Clean Architecture
  • 成功 / 失敗 / バグ / 例外
    • 常に失敗するのは バグ
    • リトライすれば成功しうるのは 例外
  • 多段式エラープルーフ
    • 早い段階でエラーに気づけば生産性を向上できる
  • 監視とは継続的なテストである
    • 運用監視は絶対に必要
    • 監視した結果"すぐに"直せれば品質は高い
  • XL
    • マイクロサービス間のテストは組み合わせ問題が発生する
    • Consumer Driven Contract Testing
    • Pact ライブラリ
    • Consumer (client) <-> Provider(server)
      • Consumer側を mock/stub感覚で書く
      • 1.Define Cosumer expectations
      • その想定をProvider側でverify
      • 2.Verify experi

まとめ

  • ベストプラクティスはまだない
  • テスタビリティの鍵はローカル実行
  • 半径の異なるフィードバックを形成する
  • 運用監視もテストと考える

AWS SAMで始めるサーバレスアプリケーション開発

16:20-

AWS Serveless Application Model(SAM)

  • サーバレスアプリケーションの管理フレームワーク
  • CloudFormation テンプレートで管理
  • Lambda, API Gateway, DynamoDBのリソース及び複数のイベントソースをサポート
  • Apache 2.0 ライセンス

サンプル

API バックエンド

  • SAMLでAPIgatewayにGET/POST/DELETEをそれぞれ定義する
  • propertyなどに名前を漬けておいたほうが管理が楽

鉄の掟

  • CI/CDパイプラインを構築しておく

    • CircleCIで構築自動化
  • 無変更->再デプロイはノンゼロ(255)が変える

  • リソース管理の抽象度

サーバレスアプリケーションのためのCI/CDパイプライン構築

17:20-

対象

  • CI/CDの基本的な用語は理解できている
  • サーバレス環境の構築

目的

  • サーバレス環境でのデプロイ手法
  • SAMを使ったデプロイ方法
  • SAMとAWS Code系の連携

CI/CDの必要性

  • リリースプロセスの4つの主なフェーズ
  • CI
    • 定期的にコードをマージ、ビルド・テストを自動で実行する
  • CD
    • 自動化されたテストを通過した後に本番へのリリース判断をした後にリリース
    • 自動化されたテストを通過した後に自動でリリース

サーバレスを取り巻く環境

  • SAM
    • サーバレスアプリに最適化されたAWS CloudFormationの拡張
    • AWS Lambda
    • API Gateway
    • Dynamo DB
    • X-ray
  • Chalice Framework
  • 3rd party
    • SERVERLESS
    • APEX
    • Claudia.js
    • Gordon

SAMとAWS Code関係サービスとの連携

AWS CodePipeLine

  • オーガナイザーとして使うのが良い
  • 1つのフェーズ内で、並列アクション、逐次アクションを設定できる

    AWS CodeCommit

  • Gitライク

    AWS CodeBuild

  • Build
  • Lambdaのzip化
  • CloudFormationのテンプレート

    AWS CloudFormation

  • デプロイ

デプロイフローをつくる

CodeStar

  • 幾つかのガイドに従うだけでデプロイワークフローを定義可能

Ci/CDのためのプログラミング

  • テストしやすい/管理しやすい単位で設計する
  • Step Functionを使って、Lambdaをファンクションレベルまでに落とす
  • AWS Lambda環境変数の利用
    • 環境変数をうまく使う