Mobile App Transformation with ECS

Mobile App Transformation with ECS

We're building the system to transform website into mobile native app. This slide describes about the architecture and the problems we have and its solution with AWS services.

B49f81194ac64f8d65bc54ffe5a2420d?s=128

Takahiro Fujiwara

December 14, 2016
Tweet

Transcript

  1. 2016 Fuller, Inc. All Rights Reserved. Mobile App Transformation with

    ECS 1 2016/12/14
  2. 2016 Fuller, Inc. All Rights Reserved. Introduction 2

  3. 2016 Fuller, Inc. All Rights Reserved. 3

  4. 2016 Fuller, Inc. All Rights Reserved. Takahiro Fujiwara (@wutali) 4

  5. 2016 Fuller, Inc. All Rights Reserved. About Joren 5

  6. Fuller, Inc. All Rights Reserved ネットだろうとリアルだろうと、サービスをやっている人な ら誰もが思うこと。それは、「お客様には一見さんではな く、常連さんになってもらいたい。」 そんな願いを叶えるために、Joren(ジョウレン)は生まれま した。

    私たちは、”ジョウレン”という言葉を世界中に広げ、世界中 のサービス提供者と利用者の距離を限りなく縮めることを目 指しています。
  7. 2016 Fuller, Inc. All Rights Reserved. 7 Jorenは、ウェブサイトのURLを入れるだけで、 魔法のようにアプリをつくれるサービスです。 ウェブサイトをスマホアプリに一発変換!

  8. Fuller, Inc. All Rights Reserved Our Customers 8 パーソナルブログ ニュースメディア

    音楽メディア テックメディア スポーツチーム コミュニティへの情報発信 大規模イベント ライフスタイルメディア Rockshot (UK) VScripts (India) J-POP SUMMIT (US) Lamar (US) Greenz ルーター芸人ブログ アルビレックス BB Rabbits Lifenet Journal
  9. Fuller, Inc. All Rights Reserved 9 Optimised user experience by

    each platforms
  10. Fuller, Inc. All Rights Reserved 10 Not web view

  11. Fuller, Inc. All Rights Reserved Joren system architecture 11 Joren

    管理ツール Android ( Java ) Joren System iOS ( Swift ) ③データ送信 Not web view 対象ウェブサイト ②アクセス コンテンツ取得 ①アプリ化したい  サイトのURLを入力 コンテンツ デザイン プッシュ通知
  12. Fuller, Inc. All Rights Reserved 12

  13. 2016 Fuller, Inc. All Rights Reserved. AWS and Joren 13

  14. Fuller, Inc. All Rights Reserved 14 Joren = + +

  15. Fuller, Inc. All Rights Reserved AWS services for Joren 15

    1. ECS (with Golang) -> APIとSQSのConsumerは全てECS上で管理 2. SQS -> クローラーの管理やDBアップデートに利用 3. DynamoDB -> 全てのデータをAPI毎にDynamoDBで管理 4. S3 -> クローリングしたコンテンツを保存 5. Lambda (with Python) -> 小さなバッチ処理に利用 6. ALB -> ECSでAPIを提供するために利用 7. SNS -> プッシュを送るために利用 8. CloudFormation -> 全てのAWSの構成を管理 9. CloudFront -> 静的サイトのホスティングに利用 10. CloudWatch Logs -> ECSのログ管理に利用
  16. Fuller, Inc. All Rights Reserved ECS services 16 合計で17のサービスが起動・AWSと連携 ->

    RESTful APIs -> Crawling Workers -> Database Syncing Workers -> Push Notification Senders -> Web Structure Analysers
  17. 2016 Fuller, Inc. All Rights Reserved. Problems 17

  18. Fuller, Inc. All Rights Reserved 18 What kind of tech

    problems we have when we started the project?
  19. 2016 Fuller, Inc. All Rights Reserved. Problems we wanna solve

    … (1) 19 インフラとWeb APIは全て一人で対応する -> インフラ管理 -> Web API開発 -> クローラー開発 -> 自動ビルド連携
  20. 2016 Fuller, Inc. All Rights Reserved. Problems we wanna solve

    … (2) 20 小さなチームから初めて、大きく育てたい -> チームメンバーの増加 -> アプリ数の増加 -> トラフィックの増加
  21. 2016 Fuller, Inc. All Rights Reserved. Problems we wanna solve

    … (3) 21 多くの外部システムと連携する -> App Storeの情報更新と監視 -> Google Playの情報更新と監視 -> iOSとAndroidの自動ビルド -> Zendeskとの連携 -> Push Notificationの送信
  22. 2016 Fuller, Inc. All Rights Reserved. Joren System Architecture 22

  23. Fuller, Inc. All Rights Reserved 23 $POTPMF "1* $POTPMF 1SFWJFX

    "QQ $SBXMFS "1* "OBMZ[FS "1* 4UPSF "1* "QQT "1* #JUSJTF "OESPJE #VJME "1* $VTUPNFS "QQT $VTUPNFS "QQT &OEVTFS "QQT 6TFS 8FC4JUFT 6TFS 8FC4JUFT $VTUPNFS 8FC4JUFT #JUSJTF J04 J5VOFT $POOFDU (PPHMF 1MBZ $SBXMFS 8PSLFS $SBXMFS 8PSLFS $SBXMFS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS &OEVTFS $VTUPNFS
  24. Fuller, Inc. All Rights Reserved 24 $POTPMF "1* $POTPMF 1SFWJFX

    "QQ $SBXMFS "1* "OBMZ[FS "1* 4UPSF "1* "QQT "1* USJTF ESPJE #VJME "1* "QQT "QQT "QQT 6TFS 6TFS 6TFS USJTF 04 5VOFT POOFDU PHMF MBZ $SBXMFS 8PSLFS $SBXMFS 8PSLFS $SBXMFS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS
  25. Fuller, Inc. All Rights Reserved 25 過去のシステムの話

  26. Fuller, Inc. All Rights Reserved When our project started …

    26 * API毎にインスタンスが起動 -> APIとワーカーは同じEC2インスタンスで管理、複数のサービスが走る状態 * インスタンスは独自のスクリプトで管理 -> Pythonとboto3、cloud-intの仕組みを使って、初期化・スタート * デプロイ時にはインスタンスを丸ごと置き換える -> インスタンスを丸ごと置き換える処理をPythonのスクリプトに書く * Internal APIの連携はVPCとRoute 53を活用 -> VPCの設定とRoute53のPrivateなDNSレコードを作って連携
  27. Fuller, Inc. All Rights Reserved 27 現在のシステムの話

  28. Fuller, Inc. All Rights Reserved 28 $POTPMF "1* $POTPMF 1SFWJFX

    "QQ $SBXMFS "1* "OBMZ[FS "1* 4UPSF "1* "QQT "1* USJTF ESPJE #VJME "1* "QQT "QQT "QQT 6TFS 6TFS 6TFS USJTF 04 5VOFT POOFDU PHMF MBZ $SBXMFS 8PSLFS $SBXMFS 8PSLFS $SBXMFS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS
  29. Fuller, Inc. All Rights Reserved Our project for now! 29

    * 全てECSクラスタ上で管理 -> 17のサービスが起動 * CircleCI上でecs-deployを実行・自動デプロイ -> GithubにPushすると、自動でDockerイメージをビルド・デプロイ * APIの設定とECSなどの構成の置き換えはCFnで行う -> ステージングと本番環境を切り替えられるCFn定義ファイルを用意 * Internal APIの連携はALBを活用 -> API毎に個別にポートを割り振り、Internal ALBがネットワークを管理
  30. Fuller, Inc. All Rights Reserved CFn Setting Example (YAML) 30

    Mappings: EnvToConfigs: staging: AccessToken: “staging-token” CrawlerApiPort: “3030” CrawlingLimit: “3” S3Bucket: “stg-bucket” production: AccessToken: “production-token” CrawlerApiPort: “3030” CrawlingLimit: “10” S3Bucket: “prd-bucket”
  31. Fuller, Inc. All Rights Reserved CFn Setting Example (YAML) 31

    Resources: TaskDefinition: Type: AWS::ECS::TaskDefinition Properties: ContainerDefinitions: - Name: CrawlerAPI Image: !Sub "${AWS::AccountId}.dkr.ecr.us-east-1.amazonaws.com/fuller-inc/walker:latest" Cpu: 50 Memory: 50 Command: - webapi Environment: - Name: PORT Value: !FindInMap [EnvToConfigs, !Ref Env, CrawlerApiPort] - Name: LIMIT Value: !FindInMap [EnvToConfigs, !Ref Env, CrawlerLimit]
  32. Fuller, Inc. All Rights Reserved 32 1. クローラーの実装と管理 2. アプリストアとの連携

    3. iOSとAndroidのアプリをビルド
  33. Fuller, Inc. All Rights Reserved 33 クローラーの実装と管理

  34. Fuller, Inc. All Rights Reserved About Our Crawler Project 34

    * Crawlerも全てGolangで実装 -> GolangはWebとの親和性が非常に高い、クローラーの実装も容易 * 管理するRESTful APIとWorkerを同じリポジトリで管理 -> リポジトリが増えないようにWorkerとAPIは同じプロジェクトとして管理 * API間は全てJSONでやり取り -> データのやり取りがわかりやすく、実装しやすいJSONフォーマットで * Restful APIのインターフェースはGolangの公開パッケージ -> Console APIにCrawler APIの依存関係を作る -> そうすることで、インターフェース変更時にバグることが少なくなった
  35. Fuller, Inc. All Rights Reserved Gaoling Code Example 35 import

    ( “http”, “github.com/fuller-inc/nwatch”, ) func main() { data := &nwatch.HookData{ URL: “https://google.com/”,
 Status: “succeed”, } if err := WebHook(); err != nil { panic(err)
 }
 } func WebHook(data *nwatch.HookData) error { _, err := http.Post(“http://joren.internal:8051/v1/hooks/data”, “application/json”, data) return err }
  36. Fuller, Inc. All Rights Reserved 36 アプリストアとの連携

  37. Fuller, Inc. All Rights Reserved About Our Store API 37

    * CrawlerのRESTful APIと同じ構成 -> Golangで実装、JSONインターフェースを持ったRestful APIを実装 * ECSクラスタ上に、Chrome Driverを起動 -> ストアの情報入力やSubmitを全てこのChrome Driverにやらせる * Chrome DriverとStore APIもJSONでやり取り -> Golangから、JSON Wired ProtocolでChrome Driverを操作
  38. Fuller, Inc. All Rights Reserved 38 アプリビルドの話

  39. Fuller, Inc. All Rights Reserved About Our App Building 39

    * Build APIも全てGolangで実装 -> Bitriseの状態を管理するシンプルな実装 * Store APIとBitrise間もJSONフォーマットで連携 -> シンプルなフォーマットでビルドリクエストをBitrise APIに投げる -> Bitriseから成功・失敗のCallbackを状態管理用のAPIで受け取る * Bitriseは便利 -> Mac OSが走るのでBitriseを使っている -> Workflowを複数定義できるので、複雑な処理をするのに便利
  40. Fuller, Inc. All Rights Reserved 40 + 開発メンバーが増えた話 + 機能追加の話

  41. Fuller, Inc. All Rights Reserved Team Building & Service Enhancement

    41 * ドメイン = リポジトリ -> ドメインをアプリリリースで必要な作業毎に定義 -> さらにドメイン = リポジトリにすることで、チームメンバーの作業を明確化 -> 現在、サーバーサイドだけで6リポジトリを運用 * 開発メンバーが増えると、1リポジトリ毎に作業を分担 -> 開発開始時から2名、サーバーサイドのエンジニアが増えた -> 現在、Analyzer APIとStore APIは別のメンバーが開発・改善 * シンプルに始めて、少しずつ改善 -> Analyzer APIは始め、DBに保存されたクローラーの定義ファイルを返していだけ -> 今はサイトを解析して、クローラーの定義ファイルを自動生成 -> そもそも、始めは全てのドメインをチームメンバーが手作業で行っていた
  42. Fuller, Inc. All Rights Reserved 42 $POTPMF "1* $POTPMF 1SFWJFX

    "QQ $SBXMFS "1* "OBMZ[FS "1* 4UPSF "1* "QQT "1* #JUSJTF "OESPJE #VJME "1* $VTUPNFS "QQT $VTUPNFS "QQT &OEVTFS "QQT 6TFS 8FC4JUFT 6TFS 8FC4JUFT 6TFS 8FC4JUFT #JUSJTF J04 J5VOFT $POOFDU (PPHMF 1MBZ $SBXMFS 8PSLFS $SBXMFS 8PSLFS $SBXMFS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS
  43. Fuller, Inc. All Rights Reserved 43 $POTPMF "1* $POTPMF 1SFWJFX

    "QQ $SBXMFS "1* "OBMZ[FS "1* 4UPSF "1* "QQT "1* #JUSJTF "OESPJE #VJME "1* $VTUPNFS "QQT $VTUPNFS "QQT &OEVTFS "QQT 6TFS 8FC4JUFT 6TFS 8FC4JUFT 6TFS 8FC4JUFT #JUSJTF J04 J5VOFT $POOFDU (PPHMF 1MBZ $SBXMFS 8PSLFS $SBXMFS 8PSLFS $SBXMFS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS
  44. Fuller, Inc. All Rights Reserved 44

  45. Fuller, Inc. All Rights Reserved 45 $POTPMF "1* $POTPMF 1SFWJFX

    "QQ $SBXMFS "1* "OBMZ[FS "1* 4UPSF "1* "QQT "1* #JUSJTF "OESPJE #VJME "1* $VTUPNFS "QQT $VTUPNFS "QQT &OEVTFS "QQT 6TFS 8FC4JUFT 6TFS 8FC4JUFT 6TFS 8FC4JUFT #JUSJTF J04 J5VOFT $POOFDU (PPHMF 1MBZ $SBXMFS 8PSLFS $SBXMFS 8PSLFS $SBXMFS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS
  46. Fuller, Inc. All Rights Reserved 46 $POTPMF "1* $POTPMF 1SFWJFX

    "QQ $SBXMFS "1* "OBMZ[FS "1* 4UPSF "1* "QQT "1* #JUSJTF "OESPJE #VJME "1* $VTUPNFS "QQT $VTUPNFS "QQT &OEVTFS "QQT 6TFS 8FC4JUFT 6TFS 8FC4JUFT 6TFS 8FC4JUFT #JUSJTF J04 J5VOFT $POOFDU (PPHMF 1MBZ $SBXMFS 8PSLFS $SBXMFS 8PSLFS $SBXMFS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS
  47. Fuller, Inc. All Rights Reserved 47 $POTPMF "1* $POTPMF 1SFWJFX

    "QQ $SBXMFS "1* "OBMZ[FS "1* 4UPSF "1* "QQT "1* #JUSJTF "OESPJE #VJME "1* $VTUPNFS "QQT $VTUPNFS "QQT &OEVTFS "QQT 6TFS 8FC4JUFT 6TFS 8FC4JUFT 6TFS 8FC4JUFT #JUSJTF J04 J5VOFT $POOFDU (PPHMF 1MBZ $SBXMFS 8PSLFS $SBXMFS 8PSLFS $SBXMFS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS "OBMZ[FS 8PSLFS
  48. Fuller, Inc. All Rights Reserved 48

  49. Fuller, Inc. All Rights Reserved 49

  50. 2016 Fuller, Inc. All Rights Reserved. Summary & Next Step

    50
  51. Fuller, Inc. All Rights Reserved Today’s summary 51 1. Golangがマイクロサービスと相性◦

    -> Golangだけで気軽に簡単にRESTful APIを作れる 2. Golang + ECSでさらに相性◎ -> RESTful APIを気軽にGolangで作って、気軽にECSにデプロイできる 3. 各APIの作業範囲を作業ベースで決める -> 多くのリポジトリを作らずに開発・運用できる 4. YAML対応したCFnは非常に便利 -> APIの設定値の環境毎の設定・変更が非常にわかりやすく書けるようになった 5. マイクロサービスを意識して設計すると作業を分担しやすい -> 機能追加・改善を少しずつ行える
  52. Fuller, Inc. All Rights Reserved We wanna develop and solve

    more things. 52 1. アプリストア操作の自動化 -> 紹介したけど、絶賛開発中。あと少し。 2. CloudFormationの自動更新 -> CFnをGitでPushした時に自動で更新するようにしたい。CodeBuildを使いたい。 3. Joren Analyticsを実装 -> CloudWatch Logs上のログ解析をそろそろ始めたい。 4. クローラーのスケーリング -> アプリ数が増えてきたので、クローラーを自動スケーリングさせたい。 5. Jorenの常連を増やす -> 当たり前にサービス利用者とアプリ数を増やしたい。増やす準備はできた!
  53. 2016 Fuller, Inc. All Rights Reserved. ありがとうございましたm(_ _)m 53