Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Serverless FrameworkでAWSフルマネージドなツールをいくつか作って得たアーキテクチャ設計の知見 / PHP Conference 2017

Serverless FrameworkでAWSフルマネージドなツールをいくつか作って得たアーキテクチャ設計の知見 / PHP Conference 2017

Ken’ichiro Oyama

October 08, 2017
Tweet

More Decks by Ken’ichiro Oyama

Other Decks in Technology

Transcript

  1. Serverless Frameworkで
    AWSフルマネージドなツールをいくつか作って得た
    アーキテクチャ設計の知⾒
    - PHPカンファレンス2017 Ver -
    Kenʼichiro Oyama
    Fusic Co.,Ltd.
    2017.10.8
    1
    PHPカンファレンス2017

    View Slide

  2. Who
    2
    PHPカンファレンス2017

    View Slide

  3. k1LoW
      Kenʼichiro Oyama
      @k1LoW
      Fusic Co.,Ltd. エンジニア
      基盤ユニット テックリード
      GitHub organizations
      fukuokarb / holiday-jp / faultline / emacs-jp / etc.
      awspecというAWS⽤のテストツールを作ってい
    ます
      https://github.com/k1LoW/awspec
    3
    PHPカンファレンス2017

    View Slide

  4. アジェンダ
      サーバーレスアーキテクチャ
      Serverless Framework
      Serverless Frameworkでの構築例
      サーバーレスアーキテクチャで構築するときに意識す
    ること
      “サーバーレスアーキテクチャで作る”という中で⽣きて
    くる設計やアイデア
    4
    PHPカンファレンス2017

    View Slide

  5. Serverless Frameworkでカジュアルに
    「サーバーレスにチャレンジしてみようかな」
    と思ってもらうことが⽬標です
    5
    PHPカンファレンス2017

    View Slide

  6. サーバーレスアーキテクチャ
    6
    PHPカンファレンス2017

    View Slide

  7. サーバーレスアーキテクチャ

      イベントドリブンなアーキテクチャ
      AWS Lambdaや* Functionsが中⼼
      サーバ単位ではなくイベント単位
      スケールの単位 / 課⾦の単位 / ⽣存期間 / 管理の単
    位 / 監視の単位
      ステートレスに構築することでクラウドが提供するス
    ケーラビリティの恩恵を受けることができる
    ※諸説あります>
    7
    PHPカンファレンス2017

    View Slide

  8. AWS Lambda
      イベント単位でコンテナが⽴ち上がりfunctionが実⾏
    される
      CGIのようなイメージ
      実⾏後のコンテナは(だいたい)破棄されるのでファ
    イルキャッシュなどステートレスな実装が求められる
      再利⽤されることもある
      ステートを持つためには他のサービスを利⽤する必要
    がある
    8
    PHPカンファレンス2017

    View Slide

  9. LAMPアーキテクチャと
    サーバーレスアーキテクチャの⽐較
    9
    PHPカンファレンス2017

    View Slide

  10. LAMPアーキテクチャ
    10
    PHPカンファレンス2017
    PHP (PHP framework)
    GET /index
    POST /create
    Apache MySQL
    public function index()
    public function create()
    Linux

    View Slide

  11. LAMPアーキテクチャ
    11
    PHPカンファレンス2017
    PHP (PHP framework)
    GET /index
    POST /create
    Apache MySQL
    public function index()
    public function create()
    Linux
    ユーザ管理領域
    (OSもミドルウェアも全部管理)

    View Slide

  12. Node
    サーバーレスアーキテクチャ(AWS)
    12
    PHPカンファレンス2017
    GET /index
    POST /create
    Lambda function
    Lambda function
    Amazon API
    Gateway
    event
    event
    Amazon Linux ( cluster )
    Amazon
    DynamoDB
    Amazon S3

    View Slide

  13. Node
    サーバーレスアーキテクチャ(AWS)
    13
    PHPカンファレンス2017
    GET /index
    POST /create
    Lambda function
    Lambda function
    Amazon API
    Gateway
    event
    event
    Amazon S3
    Lambda function
    event
    Put S3 object
    Amazon Linux ( cluster )
    Amazon
    DynamoDB
    Amazon S3

    View Slide

  14. Node
    サーバーレスアーキテクチャ(AWS)
    14
    PHPカンファレンス2017
    GET /index
    POST /create
    Lambda function
    Lambda function
    Amazon API
    Gateway
    event
    event
    Amazon S3
    Lambda function
    event
    Put S3 object
    Lambda function
    scheduled event
    CloudWatch
    Event
    Amazon Linux ( cluster )
    Amazon
    DynamoDB
    Amazon S3

    View Slide

  15. Node
    サーバーレスアーキテクチャ(AWS)
    15
    PHPカンファレンス2017
    GET /index
    POST /create
    Lambda function
    Lambda function
    Amazon API
    Gateway
    event
    event
    Amazon S3
    Lambda function
    event
    Put S3 object
    Lambda function
    scheduled event
    CloudWatch
    Event
    Amazon Linux ( cluster )
    Amazon
    DynamoDB
    Amazon S3
    And more events And more
    managed services

    View Slide

  16. Node
    サーバーレスアーキテクチャ(AWS)
    16
    PHPカンファレンス2017
    GET /index
    POST /create
    Lambda function
    Lambda function
    Amazon API
    Gateway
    event
    event
    Amazon S3
    Lambda function
    event
    Put S3 object
    Lambda function
    scheduled event
    CloudWatch
    Event
    Amazon Linux ( cluster )
    Amazon
    DynamoDB
    Amazon S3
    And more events
    ユーザ管理領域
    And more
    managed services

    View Slide

  17. 17
    PHPカンファレンス2017

    View Slide

  18. Serverless Framework
      サーバレスアーキテクチャでアプリケーションを構築する
    ためのフレームワーク
      FaaS (Function as a Service。AWSだとAWS
    Lambda) を中⼼においた開発をサポートするツール
      AWSだけでなく他のクラウドベンダが提供しているFaaS
    にも対応 (Azure Functionsなど)
      Node製
      だからといってランタイムがNodeに限定されているわけではない
    (各クラウドベンダのランタイムサポートに依存)
    18
    PHPカンファレンス2017

    View Slide

  19. で、Serverless Frameworkとは何か
      インフラもアプリケーションコードも⼀括管理できる
    デプロイツール
      Service as Code ?
      プログラマブルCFn + AWS Lambdaのコード管理
      デプロイ時に実⾏されるのはCloudFormation(AWS
    の場合)
      CFnテンプレートを動的に変更できるのでCFnよりも
    ⾃由度がある
    19
    PHPカンファレンス2017

    View Slide

  20. Node
    Serverless Frameworkで
    デプロイできる範囲(AWS)
    20
    PHPカンファレンス2017
    GET /index
    POST /create
    Lambda function
    Lambda function
    Amazon API
    Gateway
    event
    event
    Amazon S3
    Lambda function
    event
    Put S3 object
    Lambda function
    scheduled event
    CloudWatch
    Event
    Amazon Linux ( cluster )
    Amazon
    DynamoDB
    Amazon S3
    And more events And more
    managed services

    View Slide

  21. Serverless Frameworkでどのようなツール
    が作れるのか
    21
    PHPカンファレンス2017

    View Slide

  22. backslack
      Backlogの操作をSlackに通知するツール
      https://github.com/k1LoW/backslack
    22
    PHPカンファレンス2017

    View Slide

  23. backslack アーキテクチャ
    23
    PHPカンファレンス2017

    View Slide

  24. faultline
      エラートラッキングツール
      同様のSaaSだとAirbrake, Bugsnag, Rollbar
    など
      https://github.com/faultline/faultline
    24
    PHPカンファレンス2017

    View Slide

  25. faultline アーキテクチャ
    25
    PHPカンファレンス2017

    View Slide

  26. utsusemi
      APIで“動的な更新”が可能な“静的サイト”⽣成
    ツール
      動的なCMSを静的サイトとしてS3ホスティングするのに最適
      CMSの更新タイミングでAPIコールができるなら動的更新も可
    能になるし、CMS⾃体へのアクセスをなくせる
      https://github.com/k1LoW/utsusemi
    26
    PHPカンファレンス2017

    View Slide

  27. utsusemi アーキテクチャ
    27
    PHPカンファレンス2017

    View Slide

  28. hubedit
      https://hubedit.com
      GitHubのプライベートリポジトリをメモツールにする
    サービス
      GitHubを使っているので正確にはAWSフルマネージドではない
    28
    PHPカンファレンス2017

    View Slide

  29. hubedit アーキテクチャ
    29
    PHPカンファレンス2017

    View Slide

  30.  $ sls deploy
    紹介したモノは全て
    で、インフラも含めてデプロイできる
    30
    PHPカンファレンス2017

    View Slide

  31. (サンプル) faultlineのインストール
    31
    PHPカンファレンス2017
     $ git clone https://github.com/faultline/faultline.git
     $ cd faultline/
     $ npm install
     $ cp config.default.yml config.yml
     $ [Edit config.yml]
     $ AWS_PROFILE=XXXXXX sls deploy

    View Slide

  32. これだけで運⽤開始ができる
    32
    PHPカンファレンス2017

    View Slide

  33. 13 Projects
    3 Languages
    68k Errors
    1.26GB Raw logs
    33
    PHPカンファレンス2017
    Fusicでの運⽤実績

    View Slide

  34. 34
    PHPカンファレンス2017
    9< Months

    View Slide

  35. 1 Down
    0 Recovery
    35
    PHPカンファレンス2017
    ※DynamoDBのCapacityに引っかかった
    ※もともと⾃分で復旧すべきサーバがない

    View Slide

  36. faultlineのアーキテクチャ(再掲)
    36
    PHPカンファレンス2017

    View Slide

  37. Only
    3 storage
    37
    PHPカンファレンス2017

    View Slide

  38. Only 2,431 LOC
    38
    PHPカンファレンス2017
    ※Lines of Code

    View Slide

  39. たったこれだけのコードベースで
    ⼤きな効果を得られる
    39
    PHPカンファレンス2017

    View Slide

  40. サーバーレスアーキテクチャで開発する
    ということ
    40
    PHPカンファレンス2017

    View Slide

  41. LAMPアーキテクチャとは違うことを知る
      プロセスが動いているサーバにステートを持てない
      ファイルキャッシュも(ほぼ)効かない
      安易にRDMS(RDS)を使うとアンチパターン
      DBコネクションがスケールしたLambdaの接続数で…
      画像などのバイナリの取り扱いが難しい
      リクエスト/レスポンスサイズの制限
      認証・認可の仕組みの構築の仕⽅が異なる
      ファイルベースのセッションは無理
    41
    PHPカンファレンス2017

    View Slide

  42. マネージドサービスを知る
      OSSなFaaSが登場し始めているが、現状はクラウドベンダ
    が提供しているFaaSとその周辺のマネージドサービスを活
    ⽤することが多い
      オブジェクトストレージ(S3)
      NoSQL(DynamoDB)
      ストリーム(Kinesis、DynamoDB)
      ロギング(CloudWatch)
      キュー(SQS)
      認証認可(Cognito、UserPool)
      etc.
      制約を受け⼊れてうまく設計ができれば「スケール」「管理
    レス」という点でかなりインパクト⼤
      全てをマネージド(フルマネージド)にできれば最⾼
    42
    PHPカンファレンス2017

    View Slide

  43. “サーバーレスアーキテクチャで作る”
    という中で⽣きてくる設計やアイデア
    43
    PHPカンファレンス2017

    View Slide

  44. サーバーレスアーキテクチャでの設計やアイデア
      「サーバーレスデザインパターン」みたいな仰々しい
    ものではなくて、実装時に得たTips的なもの
      ただ、いろいろ試⾏錯誤をして頭をひねって思いつい
    たものばかり
      AWSのマネージドサービス前提のものもあります
      わかりやすいようにそれぞれに名前をつけています
      名前をつけることで意識する
    44
    PHPカンファレンス2017

    View Slide

  45. サーバーレスアーキテクチャでの設計やアイデア
      POST with config
      Reversed Timestamp ID
      Instant Job Queue
      S3 Object Tagging
      Env Sync 45
    PHPカンファレンス2017

    View Slide

  46. 設定値をリクエストに付与する
    ”POST with config”
    46
    PHPカンファレンス2017

    View Slide

  47. POST with config
      backslack, faultline
      設定値をツール側で保存するだけでステートの管理対
    象が増えてしまうので、できるだけ値を保持しないの
    が鉄則
      APIベースのツールなのであれば、リクエストに必要な
    設定を毎回付与してしまえばいいというアイデア
      SlackのWebhook URL, チャンネル名など
      秘匿が必要な設置値でさえもKMSを利⽤して暗号化し
    てリクエストに付与する
    47
    PHPカンファレンス2017

    View Slide

  48. backslack アーキテクチャ(再掲)
    48
    PHPカンファレンス2017

    View Slide

  49. 新しい順の⼀覧を実現する
    “Reversed Timestamp ID”
    49
    PHPカンファレンス2017

    View Slide

  50. Reversed Timestamp ID (1/2)
      faultline
      実は⼀覧を作るのは難しい
      RDSはサーバレスアーキテクチャでは⼤抵アンチパターン
      DynamoDBで「テーブルの全てのデータの⼀覧」を作るのは
    アンチパターン
      今のところS3を使うのを解にしている
      Prefixの使い⽅が設計のカギ
      /projects/{project}/errors/{message}/
    occurrences/{reversedUnixtime}.json
    50
    PHPカンファレンス2017

    View Slide

  51. Reversed Timestamp ID (2/2)
      S3のオブジェクトはアルファベット順でソートされて
    いる。`ORDER BY created DESC` を実現するにはど
    うすればいいか
      UNIX Timestampを逆カウントにして、ゼロパディン
    グすることで実現
      (Math.pow(2, 53) - 1) – unixtime
      Number.MAX_SAFE_INTEGER - unixtime
      IDから⽣成時刻もわかって便利(snowflakeみたい)
    51
    PHPカンファレンス2017

    View Slide

  52. 無限にファンアウトしかねない
    AWS Lambdaをいい感じに制限実⾏する
    ”Instant Job Queue”
    52
    PHPカンファレンス2017

    View Slide

  53. Instant Job Queue (1/2)
      utsusemi
      functionをinvokeしてページをクロールして、そのリ
    ンク先をまた同じfunctionをinvokeしてクロールし
    て...
      再帰的なinvoke
      DoSになりかねないファンアウト
      Queueを作ってWorkerプロセスを常時起動して待ち受
    ける形だとWorkerプロセスの管理が増える
      サーバーレスアーキテクチャではなくなる
      (実は)AWS Step FunctionsがAWSの解だけど費⽤が
    増える
    53
    PHPカンファレンス2017

    View Slide

  54. Instant Job Queue (2/2)
      Queue (SQS)を作ってクロール開始時にWorkerを起
    動して、Workerは指定回数デキューしてクロールした
    ら値をエンキューして同じWorkerをinvokeして⾃分⾃
    ⾝を終了
      キューにたまっているメッセージが0になったらWorkerは⾃分
    ⾃⾝を終了(最終的にWorkerは0)
      クローラのような常にキューに値がはいるパターンに使える
      同時に動かすWorker数や、Workerが処理するメッセ
    ージの数などが調整できる
      FIFOキューにしたら実⾏順番も保証される(かも)
    54
    PHPカンファレンス2017

    View Slide

  55. utsusemi アーキテクチャ(再掲)
    55
    PHPカンファレンス2017

    View Slide

  56. メタ情報を保存する
    ”S3 Object Tagging”
    56
    PHPカンファレンス2017

    View Slide

  57. S3 Object Tagging (1/2)
      utsusemi
      クローラが取得したHTMLファイルはS3バケットに保

      じゃあそのファイルの更新⽇時は?Content-Typeは?
    ETagは?
      ファイルシステムならあとでギリ取得できそうなファイルタイプ
    すらS3では難しい
      ヘッダ情報などの活⽤できそうな値は保持しなくていいのか
      他に保存する場所を作ってしまったら管理対象が増える。。。
    57
    PHPカンファレンス2017

    View Slide

  58. S3 Object Tagging (1/2)
      S3 Object Taggingを使う
      オブジェクトごとにKey-Valueの値を保持できる
      “S3 Object Tagging” はS3の機能の名前
      ユーザ情報(オブジェクト)とその住所情報(タグ)
    とか、Issue(オブジェクト)とラベル(タグ)など、
    ⽤途は広い気がする
    58
    PHPカンファレンス2017

    View Slide

  59. デプロイ時の環境変数と
    プロセス起動時の環境変数を同期させる
    ”Env Sync”
    59
    PHPカンファレンス2017

    View Slide

  60. Env Sync
      デプロイ時の環境変数とfunctionが実⾏されるコンテ
    ナの環境変数を同期させる
      The Twelve-Factor Appにある ”設定を環境変数に格
    納する”
      https://12factor.net/ja/config
      Serverless Frameworkを使っていると実装しやすい
    60
    PHPカンファレンス2017
     provider:
      name: aws
      environment: # Lambda側のコンテナに環境変数として設置する設定
      STAGE: ${env:STAGE, ’develop’} # デプロイ時に環境環境から設置

    View Slide

  61. まとめ
    61
    PHPカンファレンス2017

    View Slide

  62. まとめ
      サーバーレスアーキテクチャはハマれば強⼒
      Serverless Frameworkはインフラもアプリケーション
    コードもまとめてデプロイできる強⼒なツール
      サーバーレスアーキテクチャでうまく構築するために
    は、(例えば)LAMPアーキテクチャとは違うことを意
    識し、FaaSとその周辺のマネージドサービスの特性を
    うまく活⽤して設計をする必要がある
      “サーバーレスアーキテクチャで作る” という中で⽣き
    てくる(LAMPなアプリケーション構築とは違う)設計
    やアイデアがある(もっと知⾒をためたい)
    62
    PHPカンファレンス2017

    View Slide

  63. Letʼs `sls deploy` !!
    63
    PHPカンファレンス2017

    View Slide

  64. Thank you!
     Fusicはテクノロジーが
     好きなエンジニアを募集しています
     https://fusic.github.io 64

    View Slide