狠狠撸

狠狠撸Share a Scribd company logo
The master plan of
scaling a web application
Yusuke Wada a.k.a yusukebe
2013/10/26
Fukuoka Perl Workshop #24

1
本日の使用フォント
やさしさゴシック
http://www.fontna.com/blog/379/

2
Japan Perl Association

の

講師派遣制度を利用させて来ました

3
自己紹介

?
? (株)ワディット代表取締役
(株)オモロキ取締役兼最高技術責任者
?
? Webアプリケーションデベロッパー
物書きも少々…
?
? 独身…
和田裕介 1981年12月23日生

4
どこから来たの?

5
6
すみかは?

7
8
本題の前に

YAPC::Asia 2013レポート的な何か

9
YAPC::Aasia 2013 in Tokyo
9月19,20,21日
慶應義塾日吉キャンパス内 協生館

10
概要

?

エンジニアのエンジニアによるエンジニア
のためのお祭り

?
? 同時4トラックが走る

トータル1,131人の参加者

11
30days Albumより

http://30d.jp/yapcasia/6

12
前夜祭 LTソン::Tiny

13
お祭り雰囲気

14
トーク

15
Perl入学式

16
Lightning Talks

17
オーディエンス

18
Hub

19
引退

20
以上

YAPC::Asia 2013

ありがとう!

21
さて…

22
本日の題材
「最近なに開発してるか」

23
24
ボケて

? 国内最大級のお笑いWebサービス...らしい!
3秒で笑えるがコンセプト
?
オモロキがコアとなって開発?運営
?

25
こういうの

26
参考データ

?
? 月間お題投稿数3万件
月間ボケ投稿数120万件
?
? モバイルアプリは200万インストール
合計ボケ投稿数1,100万ボケ
?
ほげほげページビュー

27
各種デバイス展開

?
? スマホ向けWeb
iOSアプリ
?
? Androidアプリ
PC向けWeb

28
外部サービスとの連携

? Yahoo! JAPAN
百度 hao123
?
? PlayNow
goo
?
? Gunosy
etc.
?

ボケてセレクト
29
コラボ?スペシャルアカウント

?
? 企業さんがお題を提供
ユーザーがボケる
?
? バナー/告知ページ
二次利用なども
?
島耕作でボケれる!

30
ボケて自体の説明終わり

31
開発の話

32
Bokete versions

? Alpha - リリース前の試験版
Beta
- 2008年8月リリース
?
? Gamma - 2009年5月リリース
Delta - 2012年7月リリース
?
? Epsilon - 次期バージョン
33
全ての開発?運用を一人で担当
*モバイルアプリを除く

34
人的リソースは増やさない

35
便利な外部サービスでスケール

? Amazon Web Services

RDS, ElastiCache, SES ...
?
? Managedなミドルウェアを選択
GitHubプライベートレポジトリ
?
? Travis CI

Uptimer

?
などなど...
?
36
ただ、正直しんどい...

37
オモロキ

38
パートナー開発体制
ケースによって座組を変える

? コア = オモロキ
アプリ= オモロキ+ハロ+ブレイブソフト
?
? コラボ= オモロキ+ハロ+キャッチボール
...
?
39
割り切った分業化を提案

? API Version 2を作成
ほぼ全機能をWeb APIで提供
?
? モバイルアプリだけではなくWebでも利用
Webのフロント部分を誰かに移譲
?
? 言語はなんでもよい!
40
Web API v2

?
? 既存の仕様を利用する
JSON-RPC 2.0
?
? OAuth 2.0
API = Web でネットワークレイテンシ
?
? 割りきって無視をする
コアのロジックを全て実装し提供

41
JSON-RPC
# POST to SERVER	

!
{‘jsonrpc’: ‘2.0’, ‘method’: ‘/boke/recent’, ‘params’: {‘limit’: 10}, ‘id’: 1}	

!
!
# Response BODY	
{‘jsonrpc’: ‘2.0’, ‘result’: { entries = […] }, ‘id’: 1}	

シンプルなフォーマット
POSTでリクエスト
もちろんJSONフォーマット
42
43
APIの実装

? 旧APIと同居させる
認証認可のためのパス
?
? 情報操作のためのパス
v1
アプリ

OAuth
v2
JSON-RPC
44
方針

? 既存WAFは使わない = 素Plackアプリ
OAuth::Lite2 + JSON::RPCを利用
?
./lib/Bokete/WebAPIv2	
## Dispatcher.pm	
## OAuth/	
$?? ## Controller/	
$?? $?? ## OAuth.pm	
$?? $?? ## Root.pm	
$?? ## Controller.pm	
$?? ## DataHandler.pm	
$?? ## Dispatcher.pm	
## RPC/	
## Dispatcher.pm	
## Filter.pm	
## Handler/	
$?? ## Boke.pm	
$?? ## Root.pm	
## Handler.pm	
## Router.pm

45
OAuth::Lite2

?
? mixiでの利用実績あり?
継承して中身を実装する
?
? OAuth::Lite2::Server::DataHandler
code認証、password認証などに対応
?
Provider実装も含まれている

46
# In your controller	

!
use Plack::Middleware::Auth::OAuth2::ProtectedResurce;	

!
my $middleware =
Plack::Middleware::Auth::OAuth2::ProtectedResource-new(	
data_handler = 'Bokete::WebAPIv2::OAuth::DataHandler',	
app = sub {},	
);	
$middleware-call($self-request-env);	

!
if(my $user_id = $self-req-env-{REMOTE_USER}) {	
my $user = $self-model('User')-find({ id = $user_id });	
$self-stash-{user} = $user;	
}else{	
$self-stash-{user} = undef;	
}	

47
JSON::RPC

?
? ルータにRouter::Simpleを利用している
まかまかさん=牧さん

my $router = Router::Simple;	
$router-connect( 'get_info' = {	
handler = 'Hoge::Handler::Root',	
action = 'get_info'	
});	
my $dispatch = JSON::RPC::Dispatch-new( router = $router );	
...;	
sub psgi_app {	
$dispatch-handle_psgi($env);	
}

48
API Playground

49
ほぼAPI側のフレームワークは完成!

50
誰かにWebのフロントを

担当してもらおう!

51
やまぴー

52
俺「フロントの言語は何でもいいよ」

53
やまぴー「Perlでやります!」

54
俺「!!!」

55
ってことでやまぴーと一緒に

? Boketeのシステム部分をはじめて分業
? マネージメントツールをGitHubに寄せる
? レポジトリ
? イシュー管理
? ドキュメント管理
? 積極的に対面して一緒に作業する
? フロントはMojoliciousで実装する
56
Bokete::Front::*

? やまぴーが使いやすいフレームワーク作成
# presudo code	
!

get '/boke/recent' = sub {	
my $self = shift;	
my $result = $self-call_api({	
method = '/boke/recent',	
params = { limit = 10 }	
});	
$self-stash-{entries} = $result-{entries};	
$self-render();	
};
57
提供するライブラリなど

? Mojoliciousに特化したセッション管理
認証とAPIのコールをラップするUA
?
? CSRF対策
アプリのフレームワーク
?
作法をつくる
58
例えばセッション管理
my $session;	

!
...;	

!
$self-hook(	
around_dispatch = sub {	
my ( $next, $c ) =@_; 	
$session = Bokete::Session-new( request = $c-req );	
$next-();	
$session-finalize( response = $c-res );	
}	
);	

!
...;	

!
$self-helper(	
bokete_session = sub { return $session }	
);
59
特化したUserAgent
my $ua = Bokete::Front::UserAgent-new(	
client_id = ‘xxxxxx’,	
client_secret = ‘xxxxxx’,	
access_token_uri = ‘xxxxxx’,	
rpc_endpoint_uri = ‘xxxxxx’	
);	

!
my $token = $ua-get_token({	
username = ‘xxxxxx’,	
password = ‘xxxxxx’	
});	

!
# OAuthヘッダを設定しつつJSON-RPCをコールする	
my $result = $ua-call({	
access_token = $token-access_token,	
method = ‘hello’,	
params = { message = ‘foo’ }	
});
60
今回の構造化のメリット

?
? 分業しやすい、開発者の冗長化
役割としてのフォーカスが明確になる
?
? フロントエンドはやまぴー
ロジックとフレームワークづくりに集中
?
? 他のことに手を付けられる!
テスタビリティが上がる

61
今後やりたいこと

?
? 死活監視?リソース監視?チューニング
開発?CI環境の整備
?
? コンテンツデータの解析
新機能の実験
?
? Growth Hacks的なこと
インフラ周りの強化

62
まとめ

63
今やってるWebアプリの構造化

? HTTPレベルで一つのアプリを切り離す
APIサーバ
?
? OAuth認証
JSON-RPCによる情報操作API
?
? 分業出来てフォーカスが絞れる
絶賛開発中
?
? ウマくいけばやれることが広がる!
64
おわり

質問等どーぞー

65

More Related Content

The master plan of scaling a web application