71
いるけどないからつくってみたよ 高速モバイルプッシュ配信くん AWSモバイル/IoTサービス徹底攻略!! Advanced Track #1 1 Daisuke Fujimura 2015/11/21

いるけどないからつくってみたよ高速モバイルプッシュ配信くん #cmdevio

  • Upload
    fd0

  • View
    3.044

  • Download
    0

Embed Size (px)

Citation preview

いるけどないからつくってみたよ高速モバイルプッシュ配信くん

AWSモバイル/IoTサービス徹底攻略!!

Advanced Track #1

1

Daisuke Fujimura 2015/11/21

自己紹介• Daisuke Fujimura• クラスメソッド株式会社• AWS コンサルティング部• 製品開発チーム

• 以前は Web サーバサイドとかインフラ (AWS / 物理) を触ってました

• 最近ようやく Java に目覚めました2

目次• 自己紹介• 配信くん is 何?

• 利用している技術の話

3

4

配信くん is 何?

ある日のクラスメソッド社内

5

ある日のクラスメソッド社内

6

↑弊社の偉い人

ある日のクラスメソッド社内

7

任意のセグメントに効率よくプッシュ配信するミドルウェアみたいなのつくってよ。サクッと。

弊社製品開発チームの人→

ある日のクラスメソッド社内

8

任意のセグメントに効率よくプッシュ配信するミドルウェアみたいなのつくってよ。サクッと。

Σ(゚д゚) エッ!?

要求• 任意の配信先集合に対して効率良くモバイルプッシュ配信をしたい!→ Amazon SNS を使えば良さそう?

9

Amazon SNS

10

Amazon SNS• パブリッシャからトピックを経由してサブスクライバにメッセージを配送するサービス• http://docs.aws.amazon.com/ja_jp/sns/

latest/dg/welcome.html

11

Amazon SNS

12

http://docs.aws.amazon.com/ja_jp/sns/latest/dg/welcome.html より引用

方針• サブスクライバとしてモバイルデバイスをトピックに登録しておけば簡単に実現できる?

13

配信シナリオの例を考えてみる• サブスクライバ登録には API 呼出しが必要• 1 モバイルデバイス毎に最悪数秒

• 1000 件なら…

• 1000000 件なら…

• もしかして配信自体よりも準備に時間がかかる?

14

懸念• あらかじめ決まっている配信先集合の場合はトピックへの登録コストは登録時フックなどで隠蔽可能• 例 : ユーザの静的属性 (性別, 年齢, 居住地,

etc…)• そうでない (= 動的属性に基づく) 場合は前述の問題がある• 例 : ユーザの行動履歴 (購入履歴, etc…)

15

その他にも…• 任意の配信先集合は配信が完了したらどうするの?• 使用後には削除するの?• 1 アカウントあたりのトピック数には上限• http://docs.aws.amazon.com/ja_jp/

general/latest/gr/aws_service_limits.html#limits_sns

16

モバイルプッシュ通知• Amazon SNS にはトピックを使わずにパブリッシャからモバイルデバイスにプッシュ通知メッセージを直接送信する機能もある• http://docs.aws.amazon.com/ja_jp/sns/

latest/dg/SNSMobilePush.html

17

モバイルプッシュ通知

18

http://docs.aws.amazon.com/ja_jp/sns/latest/dg/SNSMobilePush.html より引用

設計• 配信先リストを渡されたら• 配信くんが (トピックの代わりに) リストを処理しつつ

• モバイルプッシュ配信をすれば• 任意の配信先集合に効率よくモバイルプッシュ配信ができそう

19

構成

20

Amazon S3

21

Amazon S3• インターネットストレージ• バケットという単位の中にオブジェクト (= ファイル)を置くことが可能

• http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/Welcome.html

22

構成

23

メッセージの例

24

{ "bucket" : “<bucket-name>", "message" : { ... }}

構成

25

Amazon SQS

26

Amazon SQS• メッセージキューサービス• SNS のサブスクライバとして登録が可能

• http://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/Welcome.html

27

構成

28

配信先リストの例

29

arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:endpoint/GCM/xxx-sns/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeearn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:endpoint/APNS/xxx-sns/aaaaaaaa-bbbb-cccc-dddd-ffffffffffff

ARN (Amazon Resouce Name) が列挙されたもの

構成

30

構成

31

構成

32

構成

33

構成

34

構成

35

構成

36

効率よく配信するためにはこれがたくさん必要となる

たくさんの EC2 で並列化• たくさんの EC2 でワークスティール• bucket にある配信先リストを並列処理• 配信先リストからの配信先分割を並列処理

• モバイルプッシュ通知を並列処理→ 課金すればするほど並列度が上がる!

37

並列化 #1

38

• bucket に置かれた配信先リストをたくさんの配信くんインスタンスで並列に読み込む

• 単一のリストファイルだとシーケンシャルにしか処理ができないという問題に対応

たくさんの EC2 で並列化• たくさんの EC2 でワークスティール• bucket にある配信先リストを並列処理• 配信先リストからの配信先分割を並列処理

• モバイルプッシュ通知を並列処理→ 課金すればするほど並列度が上がる!

39

並列化 #2

40

• 配信先リストから offset 毎に配信先を配信くんインスタンスで並列に読み込む

• Request header の Range 指定で実現• http://

docs.aws.amazon.com/ja_jp/AmazonS3/latest/API/RESTObjectGET.html

• ARN は固定長ではない → 何らかの工夫が必要

たくさんの EC2 で並列化• たくさんの EC2 でワークスティール• bucket にある配信先リストを並列処理• 配信先リストからの配信先分割を並列処理

• モバイルプッシュ通知を並列処理→ 課金すればするほど並列度が上がる!

41

並列化 #3

42

• SQS からワークスティール方式で配信くんインスタンスが配信先を取得 → 並列にモバイルプッシュ通知

たくさんの EC2 で並列化• たくさんの EC2 でワークスティール• bucket にある配信先リストを並列処理• 配信先リストからの配信先分割を並列処理

• モバイルプッシュ通知を並列処理→ 課金すればするほど並列度が上がる!

43

配信性能• 2500 push / min• t2.micro x 1 の場合の数値• インスタンスタイプは性能に影響なし• 配信くんを増やせば性能も上がる• プログラムチューニングも効果あるかも

44

まとめ (前半)• AWS ネイティブなモバイルプッシュ配信ミドルウェアを開発

• AWS で同機能が提供されたらあっさり捨てる心構えが大事• たぶんその方が高性能• あくまでも「ないからつくってみた」

45

目次• 自己紹介• 配信くん is 何?

• 利用している技術の話

46

利用している技術• Single Command Deploy• Spring Boot (Java)• Docker• Gradle• AWS• Elastic Beanstalk• CloudFormation

47

Single Command Deploy

48

Single Command Deploy• 自動ビルド厨の成れの果ての最終形• 単一コマンドですべてを完了する仕組み• Spring Boot アプリケーションを

• Docker コンテナ化し

• Gradle タスクで

• CloudFormation で構築した

• Elastic Beanstalk 環境にデプロイ

49

Single Command Deploy• 詳細は弊社都元の slideshare を参照• http://www.slideshare.net/daisuke_m/

single-command-deploy-gradleawsplugin

50

Spring Boot

51

http://projects.spring.io/spring-boot/

最近の Java フレームワーク• Play Framework• Dropwizard• Ninja Framework• Spring Boot• etc…• スタンドアロンなアプリケーションを実現• Java プロセスひとつで http サーバが起動

52

Spring Boot• 起動が簡単• $ java -jar your-app.jar• クラスパスの設定およびコンテナ準備は不要

• 設定の自動化• classpath 内のクラスの有無による自動設定• アノテーションによるカスタマイズ

• Spring Boot を使ってみよう

• http://dev.classmethod.jp/server-side/spring-boot/

53

Docker

54

https://www.docker.com/

Docker• Go 製のオープンソースの仮想化技術• アプリケーションをコンテナ化• Infrastructure as Code (Dockerfile)• VCS によるインフラ情報の管理が可能

55

Docker (for Spring Boot)• Java インストール済のファイルシステムイメージに your-app.jar を取り込んだイメージを作成

• 内部で java プロセスを起動• 環境依存を極力排除

56

Dockerfile の例# Java インストール済ファイルイメージ

FROM java:openjdk-8-jdk# 指定したポートの開放

EXPOSE 8080WORKDIR /opt/haishinkunADD your-app—x.y.z.jar /opt/haishinkunCMD /usr/bin/java -jar your-app—x.y.z.jar

57

Elastic Beanstalk

58

http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/Welcome.html

Elastic Beanstalk• AWS 上にアプリケーションの基本構成を自動構築• ELB (ロードバランサ)

• EC2 (コンピューティング資源)

• Auto Scaling (負荷分散)

• 開発者は Application Bundle を準備することでアプリケーションを構築可能

59

Application Bundle• Elastic Beanstalk の作法に従ったアプリケーションを含む zip アーカイブ• your-app.jar• Dockerfile• etc…

60

CloudFormation

61

http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html

CloudFormation• アプリケーション全体を構成する AWS 資源を定義

• Elastic Beanstalk (コンピューティング環境)

• VPC (仮想ネットワーク)

• S3 (ストレージ)

• RDS (データベース)

• etc…• Infrastructure as Code (テンプレート)

• VCS によるインフラ情報の管理が可能

62

テンプレートの例{ "AWSTemplateFormatVersion": "2010-09-09", "Description": “Your App environment template", "Parameters": { … // 構築時に決定するパラメータ … // インスタンスタイプ, 台数, SSH 接続元 IP, etc… }, "Resources": { … // 設計時に決定するリソース … // EC2, ELB, S3, RDS, etc… }}

63

CloudFormation

64

+ Parameter =

Resource Stack

Gradle

65

http://gradle.org/

Gradle• Java 製のビルド自動化ツール• タスクという単位で処理• ライブラリ管理• パッケージ作成• etc…

• Spring Boot アプリケーションの起動• spring-boot-gradle-plugin

66

Gradle の例

67

apply plugin: "java" // タスク群の追加apply plugin: "spring-boot"

task helloWorld << { // タスクの定義 println "Hello, world!"}

dependencies { // ビルド依存の定義 compile 'org.springframework.boot:spring-boot:1.3.0.RELEASE' compile 'com.amazonaws:aws-java-sdk:1.10.34'}

gradle-aws-plugin• Gradle から AWS リソースを操作するためのタスク群

• github で公開中

• https://github.com/classmethod-aws/gradle-aws-plugin

68

導入の例buildscript { repositories { mavenCentral() maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "jp.classmethod.aws:gradle-aws-plugin:0.22.2" }}

apply plugin: "jp.classmethod.aws.s3"apply plugin: "jp.classmethod.aws.cloudformation"apply plugin: "jp.classmethod.aws.beanstalk"

69

まとめ (後半)• 配信くんを構成する技術について紹介• 他の AWS ネイティブプロダクトにも応用可能• クラスメソッド製品開発チームではフル活用

70

71

ご清聴ありがとうございました