namespace api を用いたマルチテナント型 web アプリの実践

25
Namespace APIを用いた マルチテナント型Webアプリの実践 2017/03/02(木) @やっぱり App Engine ja Night #1 The Go gopher was designed by Renee French . The gopher stickers was made by Takuya Ueda. Licensed under the Creative Commons 3.0 Attributions license.

Upload: takuya-ueda

Post on 19-Mar-2017

517 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Namespace API を用いたマルチテナント型 Web アプリの実践

Namespace APIを用いたマルチテナント型Webアプリの実践

2017/03/02(木)@やっぱり App Engine ja Night #1

The Go gopher was designed by Renee French.The gopher stickers was made by Takuya Ueda.Licensed under the Creative Commons 3.0 Attributions license.

Page 2: Namespace API を用いたマルチテナント型 Web アプリの実践

自己紹介

メルカリ/ソウゾウ

上田拓也twitter: @tenntenn■ コミュニティ活動

Google Cloud Platform User Group (GCPUG) TokyoGoビギナーズgolang.tokyoGo Conference

■ 業務GAE/Goでメルカリアッテを作ってます

GoやGCPコミュニティを盛り上げる仕事

Gopherを描く仕事(LINEスタンプ)

2

Page 4: Namespace API を用いたマルチテナント型 Web アプリの実践

アジェンダ

■ 複数アプリにバナーを配信するツールの開発

● バナー配信ツールと必要とされた背景● 柔軟さと運用のしやすさの実現● 複数アプリから利用する● デモ

■ Namespace APIとマルチテナント型アプリ

● Namespace APIとは● マルチテナント型とは● マルチテナント型アプリの実現

■ まとめ

4

Page 5: Namespace API を用いたマルチテナント型 Web アプリの実践

複数のアプリにバナーを配信するツールを作る

5

Page 6: Namespace API を用いたマルチテナント型 Web アプリの実践

バナー配信ツール

■ 何をするツールか?

● モバイルアプリにバナーを配信する

● バナーの管理や配信条件を設定する

6

Page 7: Namespace API を用いたマルチテナント型 Web アプリの実践

バナー配信ツールの要件

■ 複数のアプリから利用する

● メルカリアッテとメルカリから利用

● サービス間で干渉させたくない● サービスごとの特有の処理は入れない

■ わかりやすいUI● 非エンジニアが使う

● サービスごとに別な人が入力する

■ デバッグがしやすい

● 個人環境や開発環境が作りやすい

7

Page 8: Namespace API を用いたマルチテナント型 Web アプリの実践

柔軟性と運用のしやすさの実現

■ コア部分は柔軟に

● 配信条件は式で表現

● 関数や変数も使えるようにする

■ UIはわかりやすく

● JSON Editorを用いて自動生成

● 複雑な式は入力させず組み合わせる

8

String(os) == "ios"

この話は別の機会に!

Page 9: Namespace API を用いたマルチテナント型 Web アプリの実践

複数のアプリから利用する

■ Namespace APIを使う

● Namespaceを分けることで干渉させない

● サービスごとの設定はデータとして保存○ ソースコードの中には一切書かない

● 管理コンソールのエンドポイントも分ける

9

Page 10: Namespace API を用いたマルチテナント型 Web アプリの実践

デモ

10

Page 11: Namespace API を用いたマルチテナント型 Web アプリの実践

Namespace APIとマルチテナント型のWebアプリ

11

Page 12: Namespace API を用いたマルチテナント型 Web アプリの実践

Namespace APIとは?12

■ Namespace API● Namespaceを分けることのできるAPI● 利用可能なAPI

○ Datastore, Memcache, Task Queue, Search

■ Namespaceを分ける理由

● Namespace間でデータの干渉を防ぐ

● マルチテナント型のWebアプリを作れる

Page 13: Namespace API を用いたマルチテナント型 Web アプリの実践

マルチテナント型のWebアプリとは?

■ マルチテナント型

● 1つのシステムを複数のユーザ(企業など)に提供する

■ GAEでの実現方法

13

ApplicationDatastore

NS1 NS2 NS3

Memcache

NS1 NS2 NS3

Page 14: Namespace API を用いたマルチテナント型 Web アプリの実践

Namespaceを設定する

■ Contextに埋め込む

■ Datastoreにアクセスする

14

newCtx, err := appengine.Namespace(ctx, ns)

...err = datastore.Get(newCtx, key, &val)

Contextを差し替えるだけ!

Page 15: Namespace API を用いたマルチテナント型 Web アプリの実践

Namespaceを取得する

■ 取得する関数はないのでラップする

15

type keyType stringconst key keyType = "namespace"

func WithContext(ctx context.Context, ns string)(context.Context, error) {c, err := appengine.Namespace(ctx, ns)if err != nil {...}return context.WithValue(c, key, ns), nil

}

func FromContext(ctx context.Context) string {ns, _ := ctx.Value(key).(string)return ns

}

Page 16: Namespace API を用いたマルチテナント型 Web アプリの実践

ホスト名でNamespaceを切り替える

■ Context付きのハンドラを作る

16

type AEHandler interface {ServeHTTP(c context.Context,

w http.ResponseWriter, r *http.Request) error

}type AEHandlerFunc func(...) errorfunc (f AEHandlerFunc) ServeHTTP(...) error {

return f(c, w, r)}

省略

Page 17: Namespace API を用いたマルチテナント型 Web アプリの実践

ホスト名でNamespaceを切り替える

■ ミドルウェアでNamespaceを切り替える

17

func WithNS(h AEHandler) AEHandler {return AEHandlerFunc(func(...){

ns, err := FindNS(c, r.Host)if err != nil {...}c, err = WithNamespace(c, ns)if err != nil {...}

})}

ホスト名で探す

DatastoreにNamespaceを保存

Page 18: Namespace API を用いたマルチテナント型 Web アプリの実践

URLとルーティングルール

■ GAEのURLは以下のようにアクセスできる

● Inst: インスタンス(数値)● Ver: バージョン● Serv: サービス● AppID: アプリケーションID

■ ゆるいルーティング

● インスタンス、バージョン、サービスが存在しないとデフォルトのものにルーティングされる

● インスタンスorバージョンの代わりにNamespaceを書く

18

<Inst>-dot-<Ver>-dot-<Serv>-dot-<AppID>.appspot.com

<NS>-dot-<Ver>-dot-<Serv>-dot-<AppID>.appspot.com

Page 19: Namespace API を用いたマルチテナント型 Web アプリの実践

管理用APIの分離

■ Namespaceを保存するNamespaceは?

● 管理用のNamespaceは統一しておく● アプリ全体の共通設定などに使う

○ Namespaceの管理など

■ 管理用のAPIは管理者権限を要求する

● Namespaceの保存などは管理者だけ● app.yamlで設定しておく

19

- url: /admin/api/ns/.* script: _go_app login: admin secure: always

Page 20: Namespace API を用いたマルチテナント型 Web アプリの実践

Cloud Console上での扱い

■ Cloud Datastore

■ Memcahe

20

Page 21: Namespace API を用いたマルチテナント型 Web アプリの実践

マルチテナント型にした利点

■ 他のサービス(アプリ)に影響与えない

● 見かけ上別のものになってる● データが競合しない

■ 開発環境をすぐ作れる

● Namespaceを登録すれば作れる● 同じサービス(アプリ)内でも別の用途に環境

を提供できる○ バナーだけじゃなく、他のコンテンツも

21

Page 22: Namespace API を用いたマルチテナント型 Web アプリの実践

マルチテナント型にしときの課題

■ Namespace間の設定の移行● 開発環境を用意する際にほしい

● 移行するAPIを用意する必要がある

■ バグが出ると全滅する

● すべて同じソースコードを使ってる

● バージョンをうまく使って移行する

■ ローカルでのデバッグが面倒

● ローカルのコンソールのNamespaceの対応が貧弱

● MemcacheはNamespaceを指定できない

22

Page 23: Namespace API を用いたマルチテナント型 Web アプリの実践

まとめ

■ 柔軟さと運用のしやすさのバランスは大事● 柔軟でも使いづらかったら意味がない● 工夫次第で両立することは可能

■ GAEでマルチテナント型のアプリは簡単● Namespace APIが使える

● バージョン/サービスとうまく組み合わせる

■ GAEで社内ツールを作ると便利● アクセス制御も簡単

● G Suite のアカウントも使える

23

Page 24: Namespace API を用いたマルチテナント型 Web アプリの実践

golang.tokyo ☓ GCPUG

24

4月開催予定@メルカリ発表者募集中!

Page 25: Namespace API を用いたマルチテナント型 Web アプリの実践

Thank you!

twitter: @tenntenn Qiita: tenntennconnpass: tenntenn

25