4. Agenda How to make OpenSocial Container 情報の少ない OpenSocial Container の作り方の概要について Shindig の何を利用して何を使わないか Inside Social RESTful API & JSON-RPC API 大規模ウェブアプリケーションの実際 Inside Social Activity with Q4M Q4M を利用した数万 qps を捌く非同期ジョブ
5. 1. How to make OpenSocial Container Shindig を利用した OpenSocial Container の作り方
6. What is OpenSocial Container PC の世界だと次のような定義 JavaScript API を提供している Gadget XML のパース&レンダリングが可能 また自ずと以下のような機能も要求される アプリケーションを実行する為の画面 Activity (Streams) を流すためのフィード画面 Gadget を管理する為のツール (c.f. DeNA Developer Site) などなど…
7. Terms (1) Container SNS 本体の事だと思っていい Gadget Server Gadget XML をパース&レンダリングするサーバー gadgets.io.makeRequest() などを中継する JavaScript API のコードをサーブする JavaScript API Appliacation を作る際に使える JavaScript の API Social Data (Person, Activity, Message, AppData) などにアクセス出来る
8. Terms (2) Core & Social API JSON-RPC と RESTful API の両方 JSON-RPC は表向きに出している物ではなく JavaScript API の Social Data アクセスのバックエンドとして利用 RESTful API はサーバー間でのソーシャルデータへのアクセスに利用 Mobile 向けはモバイル用の Gadget Server ( コンテンツ Proxy Server) が発行する Access Token を原則要する OAuth でアクセス。 PC 向けはすべて Consumer Request (2-legged OAuth)
12. Apache Shindig (2) どこまで使えるか Gadget Parsing & Rendering はほぼそのまま使える 認証部は自前で結合しないといけない JavaScript API は自分たちの環境に合わせて結構手直ししないといけない またオレオレ API は当然自分で実装しないとだめ RESTful & JSON-RPC は実際のデータアクセス部分を Java or PHP で記述しないと使えない
13. Apache Shindig (3) Shindig や OpenSocial と付き合う為のベストプラクティス Shindig は唯一のリファレンス実装ですが Spec 違反はざらなので転んでも泣かない! 何を使い何を作るか Container (SNS) は連携部も含め当然ながら自前で作る Gadget Parsing & Rendering は仕様がごついのと原則ほとんどそのまま使えるので Shindig の物を使う JavaScript API は手直し&追加で対応可能 Social API (RESTful & JSON-RPC) は自前でデータバインディングを実装しないと使えない 結論 Social API は自前で実装する
14. OpenSocial Architecture Container Gadget Server JavaScript API Social Data API (JSON-RPC/RESTful) Application Gadget XML Request with Authentication Fetch & Parse Render Execute XMLHttpRequest Gadget RPC External API XMLHttpRequest HTTP Request/Response Iframe Contents
16. Authentication (2) Container Gadget Server JavaScript API Social Data API (JSON-RPC/RESTful) Create and Pass Security Token Application Embed Security Token As JavaScript Code Signed Request using Security Token Signed Request using Security Token Gadget RPC using Security Token
17. Authentication (3) #!/usr/bin/perl use strict ; use warnings ; use File::Slurp qw(slurp) ; use Shindig::Authen::Java::BasicBlobCrypter; use Shindig::Authen::Java::BlobCrypterSecurityToken; my ( $container , $domain ) = ( 'default' , 'mbga-platform.jp' ); my $master_key = slurp( '/path/to/securityTokenKey' ); my $crypter = Shindig::Authen::Java::BasicBlobCrypter-> new ( master_key => $master_key ); my $token = Shindig::Authen::Java::BlobCrypterSecurityToken-> new ( $crypter , $container , $domain ); my $authen_info = +{ app_id => 12000120 , owner_id => 10020 , viewer_id => 10021 , }; for ( %$authen_info ) { $token -> $_ ( $authen_info ->{ $_ } ); } warn $token ->encrypt;
19. Shindig + Social API Gadget Server JavaScript API Social Data API (JSON-RPC/RESTful) Shindig Chariot (mobage Open Platoform API) Reverse Proxy (lighttpd) /gadgets/* /social/* XMLHttpRequest Same Origin Policy のため 同一ドメインに Shindig と API を Reverse Proxy で実現する
20. Other things その他にやるべきこと config/container.js security token を有効にする lockedDomain (app ごとに異なるドメイン ) XHR の Same Origin Policy Domain Cookie features 以下の JS の手直しや追加 JSON-RPC とのやり取りの部分とか gadgets.rpc の実装とか (updateToken など ) カスタムの JS API の実装とか
38. DBIx::Connector (2) use DBIx::Connector; use Try::Tiny; my $conn = DBIx::Connector-> new ( $dsn , $user , $pass , $attrs ); try { $conn ->txn( sub { my $dbh = shift ; ### transaction $dbh ->commit; ### Don’t forget commit!!! } ); } catch { my $e = $_ ; ### error handling };
39. SQL::Abstract::* (1) SQL は原則 SQL::Abstract で記述する 但し複雑な JOIN や GROUP BY だとかはそのままヒアドキュメントで記述する SQL_CALC_FOUND_ROWS だとか FORCE INDEX, INSERT IGNORE とかは無理やりどうにかする そろそろ新しい SQL 生成モジュールがほしい所 例によってアプリケーション全体でひとつのインスタンスでかまわないので Object::Container に入ってます
40. SQL::Abstract::* (2) LIMIT, OFFSET を使いたい SQL::Abstract::Limit で出来るよ! Bulk insert したい SQL::Abstract::Plugin::InsertMulti で出来るよ! ON DUPLICATE KEY UPDATE も出来るので (duplicate が ) 多い日でも安心です! bulk insert は 1000 件程度を上限にしてやるのがいいです 速度や Too many connection, Max allow packets の問題
41. MySQL (1) MySQL Partitioning の利用 (1) 主に日時による Range Partitioning を利用しています モバゲーマイページの「友達のゲーム状況」、「ゲームからのお知らせ」の辺り こちらはパージの手軽さが一番の利用目的 一部 List Partitioning も使っています TextData API の status 値で List Partitioning してます UNIQUE 制約が犠牲になったり外部キーが貼れなくなったりします 常にそれらとのトレードオフである事を考える
42. MySQL (2) MySQL Partitioning の利用 (2) EXPLAIN PARTITIONS SELECT … その SQL でどのパーティションが選択されるかまで分かる パーティションが絞り込めれば速度が上がる インデックスとの併用なども考えたりしてます ALTER TABLE tablename ADD PARTITIONS 追加もすぐ終わります ALTER TABLE tablename DROP PARTITIONS 削除もすぐ終わります
46. MySQL (6) Old People Old Friend People Queue Friend Queue New People New Friend People Replication Worker (Perl) Friend Replication Worker (Perl) Insert queue by trigger queue_wait() insert/update/delete insert/update/delete Slave Slave Master replication replication