SlideShare ist ein Scribd-Unternehmen logo
1 von 40
スマートフォン向けサービスにおける
          サーバサイド設計入門




            2012/09/28 hatak
            at YAPC::Asia Tokyo 2012
自己紹介
• hatak (HATAKEYAMA Hisashi)

        @hisashi

         hatak



• ネット広告会社 → ソーシャルゲーム会社

    • インフラや運用寄りの仕事をしてることが多いです

    • わりとなんでも



• インフラ / MySQL / Perl な場所に時々います
このトークの内容
• 今年春より新規サービスの立ち上げを行うことに

  • 元々インフラや運用がメインだったので、いろいろ試行錯誤することに

• このサービスを実例として紹介しながら説明

  • をしようと思ったのですが、まだリリースされていないため

• 代替の例としてシンプルな SNS を作る流れで整理・説明します



• 概説的というか、Perl に限らない話も出てきます

  • 今まで試行錯誤してみた話を整理します

  • むしろ「開発初心者が設計に入門してみました」という話かも。。

• TMTOETDI
アジェンダ
• 設計

 • サービスを作るための最初をどうやって考えていくか

• 開発

 • サーバサイドをどのように作っていったか

• 連携

 • アプリとサーバを連携させるのにどうしたか
設計   Design
今回考えるサービスの概要
• 『スマートフォン用専用アプリで利用する SNS』 を例として整理します

    • 現在開発中のサービスとは異なります。。



•   LiteSNS

    • iOS (iPhone) アプリで利用

      • 利用にはユーザ登録が必要

    • 機能

      • メッセージや写真の投稿ができる

      • 投稿にコメントやいいねがつけられる

      • 友達のフィードが見れる
そもそもアプリでなければならない?
• アプリにしなければならないか、を最初に整理してみる

 • ブラウザで閲覧するタイプのサービスではダメなのか?

  • 例) カメラやGPSなどの利用の有無

• 機能ごとに処理を行うのがサーバかクライアントかで考えてみる

 • データを保存する場所は?

 • 投稿データの編集は?

  • 例) 画像加工(リサイズ, 減色, フィルタなど)

 • SNS へのログイン・データ取得は?

  • 例) facebook にログインしてトークンを取得
ネイティブとブラウザベース
• それぞれのメリット・デメリットを踏まえておく

 • ネイティブアプリが優位な点

  • カメラやセンサーなどの利用が容易

  • アプリマーケットからの導線が期待できる

  • リッチなユーザ体験を実現しやすい

 • ブラウザベースのアプリが優位な点

  • アプリアップデート時の作業・影響が少ない

  • システム構成をシンプルに保ちやすい

• その上で特性を十分に活かせるようにした方がよい
見える側から裏側へと考えていく

• 作業に着手するのもこの順になる
 • 作りながら、互いに連携して軌道修正していく必要もある
画面 / UI を考える
• 先人に学ぶのがいいと思う

 • 自分で触ってみるのが一番

• OS のガイドラインもあるので参考にしてみる

 • iOS Human Interface Guidelines

 • Android Design ( http://developer.android.com/design/ )

• 様々な書籍も出版されている
WebAPI を考える
• method + param/body → response を考える

  • REST の考え方を取り入れつつ、使いやすい URL を考える

  • ブラウザと異なり PUT / DELETE などのメソッドも使える

• 他のサービスがどのように作っているかを調べてみる

  • 既存のサービスの API (facebook, Twitter, Google+ など)

  • フレームワークの思想 (Catalyst, Ruby on Rails)
サーバサイドを考える

• アプリケーションサーバは並列に追加できるように
• 用途に応じて複数のデータストアを用意
 • データベースサーバ (MySQL)
   • 永続的に保存するデータ
 • KVS (Redis)
   • 永続的に保存するデータ
   • DB よりもアクセス/更新などの頻度が高いもの
 • キャッシュ (memcached)
   • ローカルなキャッシュ(消えてもいい)
   • app サーバ毎に保持
LoadBalancer




   App           App                   App          App

  Nginx         Nginx                  Nginx       Nginx

 Starman       Starman             Starman        Starman

memcached    memcached           memcached      memcached




             LoadBalancer                      LoadBalancer
 DB Master                        KVS Master

  MySQL      DB Slave                  Redis   KVS Slave
               DB Slave                          KVS Slave
             MySQL                               Redis
               MySQL                               Redis
ユーザ管理

• セッションは Cookie で管理
 • OAuth なども考えたが、まずは非公開 API なのでシンプルに
 • スマートフォンアプリ側のライブラリも Cookie を処理してくれる
• アクティブなセッションが把握できる仕組みが必要
 • アプリ削除でそのまま接続できなくなったセッションの処理
 • PUSH 通知を行っても良いアクティブなセッションの把握
 • 古いセッションの Expire が必要な場合もある
 • アクティブなセッションを確認する機能
開発   Development
Perl での開発

• Perl を選んだ理由
  • 比較的勝手が分かる言語
     • 今 を取り入れてそれなりの規模の開発をできるかどうか
  • CPAN のモジュール群の魅力
• システムに依存しない環境
$ curl	
  -­‐kL	
  https://raw.github.com/gist/2775862	
  |	
  bash

  • perlbrew
     • システムの Perl を直接使いたくない
  • Carton
     • ローカルの開発環境など複数のプロジェクトが同居するときに重宝
フレームワーク

• Amon2
  • 拡張が自由にできる   自分でやらなきゃいけない

  • 仕組みを考えていく上では柔軟性が高いと思い選択


• 使ってみて
  • コード量も依存も少ないので困ったら読めばいい
  • 自分がやりやすい形に作り替えていける感じはとても良い
    • もともとの設計思想から外れてしまっているかも知れないが。。。
アプリケーションの全体構成

• Amon2::Setup::Flavor::Large を利用してスケルトンを生成
$ amon2-setup.pl --flavor=Large,Teng LiteSNS

  • これをベースとして構成を手直ししていく
• LiteSNS の中で Amon2::Web を継承したコントローラ群を複数用意
     LiteSNS::APIv1 --- API としてレスポンスを返す (JSON)

     LiteSNS::Admin --- ブラウザで閲覧する認証付き管理画面 (HTML)

• 全体で共用するモジュールはコントローラと並列の階層
     LiteSNS::Model --- ロジックをまとめたモジュール

     LiteSNS::DB --- データベースモジュール

     LiteSNS::Exceptions --- 例外モジュール
LiteSNS
├── APIv1                    API Module <Amon2::Web>
│   ├── Controller             Controller
│   │   ├── Article
│   │   ├── User
│   │   └── ...
│   ├── Dispatcher             Dispatcher
│   └── Response               Response Model
│          ├── Article
│          ├── User
│          └── ...
├── Admin                    Admin-Web Module <Amon2::Web>
│   ├── Controller
│   └── Dispatcher
├── Constants                Constant (Common)
├── DB
│   └── Main                 Main Database <Teng>
│          ├── Row
│          │  ├── Articles
│          │  ├── Users
│          │  └── ...
│          └── Schema
├── Exceptions               Exception <Class::Exception>
├── Model                    Logic Model
│   ├── Article
│   ├── User
│   └── ...
└── Util                     UtilityMethods (Common)
LiteSNS::DB

• ORM として Teng を利用
 • あとでモデルでちゃんと SQL 整理すればいい
   • でも、インデックスなどをしっかり考えると整理はあった方がいい
 • 管理画面のようなケースはORMのままでもいいと思う
• データセット毎に別のクラスとして用意
 • 複数系統持つことになると思うので
 • データセットや master / slave をつなぎ替えられるように
• 日付や定義値などのカラムは inflate / deflate 設定しておく
データの論理削除

• 全テーブルにフラグ (row_status) を持たせておく
    1 : enable

    0 : disable

   -1 : deleted

• DB クラスで Class::Method::Modifiers を使う
  • delete メソッドを置き換えてしまう
package LiteSNS::DB::Main;
use parent qw(Teng);
use Class::Method::Modifiers;
use DateTime;

use constant STATUS => {
    ENABLE => 1,      # 有効
    DISABLE => 0,     # 無効
    DELETED => -1,    # 削除
};

around delete => sub {
    my ($orig, $self, $table_name, $delete_condition) = @_;
    my $update_row_data = {
        updated_at => DateTime->now(time_zone => 'Asia/Tokyo'),
        row_status => STATUS()->{DELETED},
    };
    $self->update($table_name, $update_row_data, $delete_condition);
};

before single => sub {
    my ($self, $table_name, $search_condition, $search_attr) = @_;
    unless (defined $search_condition->{row_status}) {
        $search_condition->{row_status} = STATUS()->{ENABLE};
    }
};

...
LiteSNS::Model

• 共通の処理として呼べるようにコントローラから分離
 • API だけでなく、Admin や CLI からも同じ処理をする可能性があるため
 • Mouse ベースでリクエストに依存しない処理をまとめたクラスを作成
• 常に決まった処理をするようなロジックをまとめる
 • フローに沿ったステータスの遷移
   • 例) 友達の状態をチェックして申請中 → 承認にステータスを変える
 • 合計数のインクリメント/デクリメント
   • 例) コメントを投稿したら、その記事のコメント数をインクリメント
LiteSNS::APIv1::Response

• レスポンスを詰め込むオブジェクトを用意
 • 入れ子構造
 • 不要カラムの削除や属性名の変更など
• Teng::Row を詰め込んで JSON で出力したいハッシュに変換・整形
 • 最初は Teng::Row に変換メソッドを組み込んでみた
 • テーブルとモデルが必ずしも一対一対応しなかったので分離
users                {
                                        id => 928,
               id                       user => {
                                           id => 1001,
               name                        name => ‘taro’,
                                        },
               password
articles                                title => ‘今日のランチ’,
               article_count            body => ‘パンがおいしかった!’,
 id                                     createdAt => ‘2012-09-28 13:24:01’,
               row_status               comments => [
 user_id                                   {
               created_at                     user => {
 title
               updated_at                        id => 1034,
 body                                            name => ‘jiro’,
                                              },
 comment_count                                body => ‘おいしそうだね!’,
 like_count                                   createdAt => ‘2012-09-28 13:31:34’,
                                           },
 row_status         comments               {
                                              user => {
 created_at           id                         id => 1001,
 updated_at           user_id                    name => ‘taro’,
                                              },
                      article_id              body => ‘焼きたてをだしてくれるん
                                              だー’,
                      body                    createdAt => ‘2012-09-28 13:35:18’,
                      row_status           },
                                        ],
                      created_at   },
                      updated_at
JSON レスポンスの生成

• 標準プラグイン Amon2::Plugin::Web::JSON を利用
  • 今回はレスポンスコードを変えたかったので一部変更
    • Controller からの戻り値でレスポンスコードを渡せるように


• JSON / JSON::XS
  • PERL -> JSON では数字の取り扱いに注意
    • 類推してくれるが、明示的に数値になっていないと数値にならない
エラーと例外の処理

• Class::Exception を利用
  • アプリケーション共通で利用する例外クラスを作成
  • 例外が発生した場合にこのインスタンスを投げる
• Dispatcher / Worker のレベルで Exception をキャッチする
  • 該当する例外の内容に合わせてエラーメッセージを生成
  • HTTP ステータスコードに割り当ててレスポンスとして作成
テスト

• Model や共通関数などはテストを作っておく
 • 実際に処理させてチェックだと面倒
 • テストに合わせて daemon を起動するようにしてあげると良い
   • http://perl-users.jp/articles/advent-calendar/2011/test/18
• テストを書きすぎるとキリが無くなってしまうのでバランス大事
 • Jenkins などの CI ツールをうまく活用
• API はレスポンスのテストしやすい
 • JSON なので期待値との比較などが容易
 • Test::WWW::Mechanize::PSGI などを活用
環境ごとの切り分け

• Amon2 の機能で config を切り替えられる
  • 接続先ホストやユーザ名などを変えておく
  • 開発時だけ環境変数でフラグを入れたりすると便利
• 本番と開発環境でドメイン + 階層が異なってもうまく吸収できる
  • 同一ドメインで全てをサーブしたい場合はまとめた psgi を作ってたてる
# app.psgi
...
builder {
    mount '/api/' => Plack::Util::load_psgi('api.psgi');
    mount '/admin/' => Plack::Util::load_psgi('admin.psgi');
};


  • 異なるドメインの場合は個別にプロセスをたてる
      • Proxy などでわけてアクセスできるようにする
本番環境

• Starman + Server::Starter
$ carton	
  exec	
  -­‐-­‐	
  start_server	
  -­‐-­‐port=5000	
  -­‐-­‐signal-­‐on-­‐hup=USR1	
  -­‐-­‐	
  
plackup	
  -­‐s	
  Starlet	
  -­‐-­‐spawn-­‐interval=5


   • プロセスを supervisord で立ち上げる
       • 標準出力のログは supervisord がファイルに書き出してくれる
• ローカルに Nginx をたててローカルの Starman に送る
   • Nginx 側でアクセスログを取得
   • 管理画面のアクセス制御や多段 Proxy 時のヘッダコントロールなど
連携   Cooperation
クライアントアプリとの連携

• iPhone を例にいくつか紹介
  • Objective-C 的な話も出てきますが軽く触れるだけにします


• AFNetworking (https://github.com/AFNetworking/AFNetworking)

  • AFJSONRequestOperation で JSON -> NSDirectory と変換

  • NSDirectory で init できるようにデータオブジェクトを定義しておく

    • オブジェクトが入れ子になっているようにしておく

  • このクラスがあるから、API の出力も同じようにできるオブジェクトを考
    えてるわけで
API のコールと JSON 値の変換
• 1回のリクエストで階層化したデータを返せるようにする

 • 通信回数を抑えることが大事

  • 画面遷移の度に通信を発生させたくない

 • 海外を見据えてるなら通信環境が優れている場所ばかりとは限らないため



• 値を変更したらその変更を通知して画面も更新する必要がある

• インターフェイスとのバランスも考える必要がある

 • 送信 ボタンがあるとは限らず、トリガスイッチだけだったりもする



• アプリ開発者と連携しながら相互に調整する必要がある
リクエストヘッダ

• 独自のユーザエージェントを設定
• 独自の HTTP ヘッダをアプリからの通信時に埋め込む
 • クライアントアプリのバージョン
   • X-LiteSNS-Version
 • ユーザの閲覧環境
   • X-LiteSNS-Locale
   • X-LiteSNS-Language
   • X-LiteSNS-Timezone
• このあたりはアプリサイドのコードで埋め込むことができる
 • ルールを決めておくことが大事
APNS を用いた PUSH 通知

• Apple Push Notification Service (APNS)
  • 詳細は iOS Developer Library を参照
• 通知の流れ
  1.アプリでデバイストークンを取得してサーバに送信

     • NSData を16進数などに変換してサーバに POST
  2.サーバサイドでアクティブなセッションと紐づけて保持しておく

  3.モジュールを利用して通知パケットを APNS サーバに送る

     • Net::APNS, AnyEvent::APNS
• AnyEvent::APNS の例は typester さんの解説が分かりやすいです
  • http://perl-users.jp/articles/advent-calendar/2010/hacker/7
-­‐(void)applicationDidFinishLaunching:(UIApplication	
  *)application	
  
{	
  	
  	
  	
  
	
  	
  	
  	
  //	
  初回起動時に	
  「“LiteSNS”はあなたにプッシュ通知を..」	
  という確認ダイアログを表示
	
  	
  	
  	
  [[UIApplication	
  sharedApplication]	
  registerForRemoteNotificationTypes:
                                            (UIRemoteNotificationTypeAlert
                                            	
  |	
  UIRemoteNotificationTypeBadge
                                                | UIRemoteNotificationTypeSound)];
}

-­‐	
  (void)application:(UIApplication	
  *)app	
  didRegisterForRemoteNotificationsWithDeviceToken:
(NSData	
  *)deviceToken	
  
{	
  
	
  	
  	
  	
  //	
  ここで	
  NSData	
  形式の	
  deviceToken	
  を16進数変換して送ります
}


use Net::APNS;

my $APNS = Net::APNS->new;

my $notification = $APNS->notify({
        cert   => ‘path/to/app.cer’,
        key    => ‘path/to/app.key’,
    });
$notification->devicetoken(‘device_token’); # ここで16進数のトークンをセットする
$notification->message("new message from LiteSNS"); # 通知メッセージ本文
$notification->badge(1); # アプリアイコンにつけるバッジの数

$notification->write;
まとめ   Summary
まとめ
• 設計

 • 見えるところから見えないところへと考えを掘り下げていく

 • 最初に全てを決めきれないので、作りながら微調整は必要

• 開発

 • 仕組みを考えながら組み合わせて作っていく

 • スケールする仕組みをあとからでも入れられるようにする

• 連携

 • ライブラリをうまく使ってデータを組み立てていく

 • スマートフォンならでは、アプリならではの視点も必要
まとめ
• やってみて分かったこと

 • 様々な観点が必要とされている

   • プログラム、ミドルウェア、に加えてフロント側も

   • 特性とかユーザの利用シーンもちゃんと考えないとうまく作れない

 • でも、難しいことではない

   • (本来は)全部を一人でできなくてもいい

   • タスクを振るとき、全体を設計するときにあると良い

 • 何ができるか、を知っていることが大事

   • Titanium など敷居の低い開発手法もあるので試してみるのが良い
ご清聴ありがとうございました!

Weitere ähnliche Inhalte

Was ist angesagt?

SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
ゲームエンジニアのためのデータベース設計
ゲームエンジニアのためのデータベース設計ゲームエンジニアのためのデータベース設計
ゲームエンジニアのためのデータベース設計sairoutine
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装infinite_loop
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.kiki utagawa
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean ArchitectureAtsushi Nakamura
 
BuildKitの概要と最近の機能
BuildKitの概要と最近の機能BuildKitの概要と最近の機能
BuildKitの概要と最近の機能Kohei Tokunaga
 
新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編infinite_loop
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるpospome
 
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)NTT DATA Technology & Innovation
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターンSoudai Sone
 
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニックinfinite_loop
 
PHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことPHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことKentaro Matsui
 
Cognitive Complexity でコードの複雑さを定量的に計測しよう
Cognitive Complexity でコードの複雑さを定量的に計測しようCognitive Complexity でコードの複雑さを定量的に計測しよう
Cognitive Complexity でコードの複雑さを定量的に計測しようShuto Suzuki
 
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムMySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムKouhei Sutou
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 

Was ist angesagt? (20)

SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
Docker Compose 徹底解説
Docker Compose 徹底解説Docker Compose 徹底解説
Docker Compose 徹底解説
 
ゲームエンジニアのためのデータベース設計
ゲームエンジニアのためのデータベース設計ゲームエンジニアのためのデータベース設計
ゲームエンジニアのためのデータベース設計
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
BuildKitの概要と最近の機能
BuildKitの概要と最近の機能BuildKitの概要と最近の機能
BuildKitの概要と最近の機能
 
新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
 
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターン
 
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
 
PHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったことPHPで大規模ブラウザゲームを開発してわかったこと
PHPで大規模ブラウザゲームを開発してわかったこと
 
Cognitive Complexity でコードの複雑さを定量的に計測しよう
Cognitive Complexity でコードの複雑さを定量的に計測しようCognitive Complexity でコードの複雑さを定量的に計測しよう
Cognitive Complexity でコードの複雑さを定量的に計測しよう
 
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムMySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 

Andere mochten auch

通信対戦ゲームを作った話
通信対戦ゲームを作った話通信対戦ゲームを作った話
通信対戦ゲームを作った話mipsparc
 
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみたYuusuke Takeuchi
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介Shinya Okano
 
Djangoによるスマホアプリバックエンドの実装
Djangoによるスマホアプリバックエンドの実装Djangoによるスマホアプリバックエンドの実装
Djangoによるスマホアプリバックエンドの実装Nakazawa Yuichi
 
自宅で出来る!ゲームサーバの作り方
自宅で出来る!ゲームサーバの作り方自宅で出来る!ゲームサーバの作り方
自宅で出来る!ゲームサーバの作り方光晶 上原
 
ゲームサーバ開発現場の考え方
ゲームサーバ開発現場の考え方ゲームサーバ開発現場の考え方
ゲームサーバ開発現場の考え方Daisaku Mochizuki
 
年の瀬!リアルタイム通信ゲームサーバ勉強会
年の瀬!リアルタイム通信ゲームサーバ勉強会年の瀬!リアルタイム通信ゲームサーバ勉強会
年の瀬!リアルタイム通信ゲームサーバ勉強会monobit
 

Andere mochten auch (7)

通信対戦ゲームを作った話
通信対戦ゲームを作った話通信対戦ゲームを作った話
通信対戦ゲームを作った話
 
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
Djangoによるスマホアプリバックエンドの実装
Djangoによるスマホアプリバックエンドの実装Djangoによるスマホアプリバックエンドの実装
Djangoによるスマホアプリバックエンドの実装
 
自宅で出来る!ゲームサーバの作り方
自宅で出来る!ゲームサーバの作り方自宅で出来る!ゲームサーバの作り方
自宅で出来る!ゲームサーバの作り方
 
ゲームサーバ開発現場の考え方
ゲームサーバ開発現場の考え方ゲームサーバ開発現場の考え方
ゲームサーバ開発現場の考え方
 
年の瀬!リアルタイム通信ゲームサーバ勉強会
年の瀬!リアルタイム通信ゲームサーバ勉強会年の瀬!リアルタイム通信ゲームサーバ勉強会
年の瀬!リアルタイム通信ゲームサーバ勉強会
 

Ähnlich wie スマートフォン向けサービスにおけるサーバサイド設計入門

CodeIgniter入門
CodeIgniter入門CodeIgniter入門
CodeIgniter入門Sho A
 
ASP.NET Core WebAPIでODataを使おう
ASP.NET Core WebAPIでODataを使おうASP.NET Core WebAPIでODataを使おう
ASP.NET Core WebAPIでODataを使おうDevTakas
 
Awsで構築したのだよ 05 プロセス監視、メモリ使用率、ディスク使用率をCloudWatchのカスタムメトリクスに追加したい
Awsで構築したのだよ 05 プロセス監視、メモリ使用率、ディスク使用率をCloudWatchのカスタムメトリクスに追加したいAwsで構築したのだよ 05 プロセス監視、メモリ使用率、ディスク使用率をCloudWatchのカスタムメトリクスに追加したい
Awsで構築したのだよ 05 プロセス監視、メモリ使用率、ディスク使用率をCloudWatchのカスタムメトリクスに追加したい聡 大久保
 
脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_QueryHidekazu Ishikawa
 
Webサーバのチューニング
WebサーバのチューニングWebサーバのチューニング
WebサーバのチューニングYu Komiya
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回Naoyuki Yamada
 
PHPフレームワーク入門
PHPフレームワーク入門PHPフレームワーク入門
PHPフレームワーク入門Sho A
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 
Cloudstack user group meeting in osaka
Cloudstack user group meeting in osakaCloudstack user group meeting in osaka
Cloudstack user group meeting in osakaNaotaka Jay HOTTA
 
Azure でサーバーレス、 Infrastructure as Code どうしてますか?
Azure でサーバーレス、 Infrastructure as Code どうしてますか?Azure でサーバーレス、 Infrastructure as Code どうしてますか?
Azure でサーバーレス、 Infrastructure as Code どうしてますか?Kazumi IWANAGA
 
おすすめ gem
おすすめ gemおすすめ gem
おすすめ gemchocoby
 
activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介Kevin Toyoda
 
Rails Controller Fundamentals
Rails Controller FundamentalsRails Controller Fundamentals
Rails Controller FundamentalsTakashi SAKAGUCHI
 
Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識shigeya
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2Nishida Kansuke
 
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...Naoya Ito
 
WTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniterWTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniterMasanori Oobayashi
 
PHP開発者のためのNoSQL入門
PHP開発者のためのNoSQL入門PHP開発者のためのNoSQL入門
PHP開発者のためのNoSQL入門じゅん なかざ
 
20091030cakephphandson 01
20091030cakephphandson 0120091030cakephphandson 01
20091030cakephphandson 01Yusuke Ando
 

Ähnlich wie スマートフォン向けサービスにおけるサーバサイド設計入門 (20)

CodeIgniter入門
CodeIgniter入門CodeIgniter入門
CodeIgniter入門
 
ASP.NET Core WebAPIでODataを使おう
ASP.NET Core WebAPIでODataを使おうASP.NET Core WebAPIでODataを使おう
ASP.NET Core WebAPIでODataを使おう
 
Awsで構築したのだよ 05 プロセス監視、メモリ使用率、ディスク使用率をCloudWatchのカスタムメトリクスに追加したい
Awsで構築したのだよ 05 プロセス監視、メモリ使用率、ディスク使用率をCloudWatchのカスタムメトリクスに追加したいAwsで構築したのだよ 05 プロセス監視、メモリ使用率、ディスク使用率をCloudWatchのカスタムメトリクスに追加したい
Awsで構築したのだよ 05 プロセス監視、メモリ使用率、ディスク使用率をCloudWatchのカスタムメトリクスに追加したい
 
脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query
 
Webサーバのチューニング
WebサーバのチューニングWebサーバのチューニング
Webサーバのチューニング
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 
PHPフレームワーク入門
PHPフレームワーク入門PHPフレームワーク入門
PHPフレームワーク入門
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
Cloudstack user group meeting in osaka
Cloudstack user group meeting in osakaCloudstack user group meeting in osaka
Cloudstack user group meeting in osaka
 
Azure でサーバーレス、 Infrastructure as Code どうしてますか?
Azure でサーバーレス、 Infrastructure as Code どうしてますか?Azure でサーバーレス、 Infrastructure as Code どうしてますか?
Azure でサーバーレス、 Infrastructure as Code どうしてますか?
 
おすすめ gem
おすすめ gemおすすめ gem
おすすめ gem
 
activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介
 
Rails Controller Fundamentals
Rails Controller FundamentalsRails Controller Fundamentals
Rails Controller Fundamentals
 
Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2
 
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
 
WTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniterWTM53 phpフレームワーク いまさらcodeigniter
WTM53 phpフレームワーク いまさらcodeigniter
 
Redmine Ansible
Redmine AnsibleRedmine Ansible
Redmine Ansible
 
PHP開発者のためのNoSQL入門
PHP開発者のためのNoSQL入門PHP開発者のためのNoSQL入門
PHP開発者のためのNoSQL入門
 
20091030cakephphandson 01
20091030cakephphandson 0120091030cakephphandson 01
20091030cakephphandson 01
 

Kürzlich hochgeladen

スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 

Kürzlich hochgeladen (10)

スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 

スマートフォン向けサービスにおけるサーバサイド設計入門

  • 1. スマートフォン向けサービスにおける サーバサイド設計入門 2012/09/28 hatak at YAPC::Asia Tokyo 2012
  • 2. 自己紹介 • hatak (HATAKEYAMA Hisashi) @hisashi hatak • ネット広告会社 → ソーシャルゲーム会社 • インフラや運用寄りの仕事をしてることが多いです • わりとなんでも • インフラ / MySQL / Perl な場所に時々います
  • 3. このトークの内容 • 今年春より新規サービスの立ち上げを行うことに • 元々インフラや運用がメインだったので、いろいろ試行錯誤することに • このサービスを実例として紹介しながら説明 • をしようと思ったのですが、まだリリースされていないため • 代替の例としてシンプルな SNS を作る流れで整理・説明します • 概説的というか、Perl に限らない話も出てきます • 今まで試行錯誤してみた話を整理します • むしろ「開発初心者が設計に入門してみました」という話かも。。 • TMTOETDI
  • 4. アジェンダ • 設計 • サービスを作るための最初をどうやって考えていくか • 開発 • サーバサイドをどのように作っていったか • 連携 • アプリとサーバを連携させるのにどうしたか
  • 5. 設計 Design
  • 6. 今回考えるサービスの概要 • 『スマートフォン用専用アプリで利用する SNS』 を例として整理します • 現在開発中のサービスとは異なります。。 • LiteSNS • iOS (iPhone) アプリで利用 • 利用にはユーザ登録が必要 • 機能 • メッセージや写真の投稿ができる • 投稿にコメントやいいねがつけられる • 友達のフィードが見れる
  • 7. そもそもアプリでなければならない? • アプリにしなければならないか、を最初に整理してみる • ブラウザで閲覧するタイプのサービスではダメなのか? • 例) カメラやGPSなどの利用の有無 • 機能ごとに処理を行うのがサーバかクライアントかで考えてみる • データを保存する場所は? • 投稿データの編集は? • 例) 画像加工(リサイズ, 減色, フィルタなど) • SNS へのログイン・データ取得は? • 例) facebook にログインしてトークンを取得
  • 8. ネイティブとブラウザベース • それぞれのメリット・デメリットを踏まえておく • ネイティブアプリが優位な点 • カメラやセンサーなどの利用が容易 • アプリマーケットからの導線が期待できる • リッチなユーザ体験を実現しやすい • ブラウザベースのアプリが優位な点 • アプリアップデート時の作業・影響が少ない • システム構成をシンプルに保ちやすい • その上で特性を十分に活かせるようにした方がよい
  • 9. 見える側から裏側へと考えていく • 作業に着手するのもこの順になる • 作りながら、互いに連携して軌道修正していく必要もある
  • 10. 画面 / UI を考える • 先人に学ぶのがいいと思う • 自分で触ってみるのが一番 • OS のガイドラインもあるので参考にしてみる • iOS Human Interface Guidelines • Android Design ( http://developer.android.com/design/ ) • 様々な書籍も出版されている
  • 11. WebAPI を考える • method + param/body → response を考える • REST の考え方を取り入れつつ、使いやすい URL を考える • ブラウザと異なり PUT / DELETE などのメソッドも使える • 他のサービスがどのように作っているかを調べてみる • 既存のサービスの API (facebook, Twitter, Google+ など) • フレームワークの思想 (Catalyst, Ruby on Rails)
  • 12. サーバサイドを考える • アプリケーションサーバは並列に追加できるように • 用途に応じて複数のデータストアを用意 • データベースサーバ (MySQL) • 永続的に保存するデータ • KVS (Redis) • 永続的に保存するデータ • DB よりもアクセス/更新などの頻度が高いもの • キャッシュ (memcached) • ローカルなキャッシュ(消えてもいい) • app サーバ毎に保持
  • 13. LoadBalancer App App App App Nginx Nginx Nginx Nginx Starman Starman Starman Starman memcached memcached memcached memcached LoadBalancer LoadBalancer DB Master KVS Master MySQL DB Slave Redis KVS Slave DB Slave KVS Slave MySQL Redis MySQL Redis
  • 14. ユーザ管理 • セッションは Cookie で管理 • OAuth なども考えたが、まずは非公開 API なのでシンプルに • スマートフォンアプリ側のライブラリも Cookie を処理してくれる • アクティブなセッションが把握できる仕組みが必要 • アプリ削除でそのまま接続できなくなったセッションの処理 • PUSH 通知を行っても良いアクティブなセッションの把握 • 古いセッションの Expire が必要な場合もある • アクティブなセッションを確認する機能
  • 15. 開発 Development
  • 16. Perl での開発 • Perl を選んだ理由 • 比較的勝手が分かる言語 • 今 を取り入れてそれなりの規模の開発をできるかどうか • CPAN のモジュール群の魅力 • システムに依存しない環境 $ curl  -­‐kL  https://raw.github.com/gist/2775862  |  bash • perlbrew • システムの Perl を直接使いたくない • Carton • ローカルの開発環境など複数のプロジェクトが同居するときに重宝
  • 17. フレームワーク • Amon2 • 拡張が自由にできる 自分でやらなきゃいけない • 仕組みを考えていく上では柔軟性が高いと思い選択 • 使ってみて • コード量も依存も少ないので困ったら読めばいい • 自分がやりやすい形に作り替えていける感じはとても良い • もともとの設計思想から外れてしまっているかも知れないが。。。
  • 18. アプリケーションの全体構成 • Amon2::Setup::Flavor::Large を利用してスケルトンを生成 $ amon2-setup.pl --flavor=Large,Teng LiteSNS • これをベースとして構成を手直ししていく • LiteSNS の中で Amon2::Web を継承したコントローラ群を複数用意 LiteSNS::APIv1 --- API としてレスポンスを返す (JSON) LiteSNS::Admin --- ブラウザで閲覧する認証付き管理画面 (HTML) • 全体で共用するモジュールはコントローラと並列の階層 LiteSNS::Model --- ロジックをまとめたモジュール LiteSNS::DB --- データベースモジュール LiteSNS::Exceptions --- 例外モジュール
  • 19. LiteSNS ├── APIv1 API Module <Amon2::Web> │   ├── Controller Controller │   │   ├── Article │   │   ├── User │   │   └── ... │   ├── Dispatcher Dispatcher │   └── Response Response Model │      ├── Article │      ├── User │      └── ... ├── Admin Admin-Web Module <Amon2::Web> │   ├── Controller │   └── Dispatcher ├── Constants Constant (Common) ├── DB │   └── Main Main Database <Teng> │      ├── Row │      │  ├── Articles │      │  ├── Users │   │  └── ... │      └── Schema ├── Exceptions Exception <Class::Exception> ├── Model Logic Model │   ├── Article │   ├── User │   └── ... └── Util UtilityMethods (Common)
  • 20. LiteSNS::DB • ORM として Teng を利用 • あとでモデルでちゃんと SQL 整理すればいい • でも、インデックスなどをしっかり考えると整理はあった方がいい • 管理画面のようなケースはORMのままでもいいと思う • データセット毎に別のクラスとして用意 • 複数系統持つことになると思うので • データセットや master / slave をつなぎ替えられるように • 日付や定義値などのカラムは inflate / deflate 設定しておく
  • 21. データの論理削除 • 全テーブルにフラグ (row_status) を持たせておく 1 : enable 0 : disable -1 : deleted • DB クラスで Class::Method::Modifiers を使う • delete メソッドを置き換えてしまう
  • 22. package LiteSNS::DB::Main; use parent qw(Teng); use Class::Method::Modifiers; use DateTime; use constant STATUS => { ENABLE => 1, # 有効 DISABLE => 0, # 無効 DELETED => -1, # 削除 }; around delete => sub { my ($orig, $self, $table_name, $delete_condition) = @_; my $update_row_data = { updated_at => DateTime->now(time_zone => 'Asia/Tokyo'), row_status => STATUS()->{DELETED}, }; $self->update($table_name, $update_row_data, $delete_condition); }; before single => sub { my ($self, $table_name, $search_condition, $search_attr) = @_; unless (defined $search_condition->{row_status}) { $search_condition->{row_status} = STATUS()->{ENABLE}; } }; ...
  • 23. LiteSNS::Model • 共通の処理として呼べるようにコントローラから分離 • API だけでなく、Admin や CLI からも同じ処理をする可能性があるため • Mouse ベースでリクエストに依存しない処理をまとめたクラスを作成 • 常に決まった処理をするようなロジックをまとめる • フローに沿ったステータスの遷移 • 例) 友達の状態をチェックして申請中 → 承認にステータスを変える • 合計数のインクリメント/デクリメント • 例) コメントを投稿したら、その記事のコメント数をインクリメント
  • 24. LiteSNS::APIv1::Response • レスポンスを詰め込むオブジェクトを用意 • 入れ子構造 • 不要カラムの削除や属性名の変更など • Teng::Row を詰め込んで JSON で出力したいハッシュに変換・整形 • 最初は Teng::Row に変換メソッドを組み込んでみた • テーブルとモデルが必ずしも一対一対応しなかったので分離
  • 25. users { id => 928, id user => { id => 1001, name name => ‘taro’, }, password articles title => ‘今日のランチ’, article_count body => ‘パンがおいしかった!’, id createdAt => ‘2012-09-28 13:24:01’, row_status comments => [ user_id { created_at user => { title updated_at id => 1034, body name => ‘jiro’, }, comment_count body => ‘おいしそうだね!’, like_count createdAt => ‘2012-09-28 13:31:34’, }, row_status comments { user => { created_at id id => 1001, updated_at user_id name => ‘taro’, }, article_id body => ‘焼きたてをだしてくれるん だー’, body createdAt => ‘2012-09-28 13:35:18’, row_status }, ], created_at }, updated_at
  • 26. JSON レスポンスの生成 • 標準プラグイン Amon2::Plugin::Web::JSON を利用 • 今回はレスポンスコードを変えたかったので一部変更 • Controller からの戻り値でレスポンスコードを渡せるように • JSON / JSON::XS • PERL -> JSON では数字の取り扱いに注意 • 類推してくれるが、明示的に数値になっていないと数値にならない
  • 27. エラーと例外の処理 • Class::Exception を利用 • アプリケーション共通で利用する例外クラスを作成 • 例外が発生した場合にこのインスタンスを投げる • Dispatcher / Worker のレベルで Exception をキャッチする • 該当する例外の内容に合わせてエラーメッセージを生成 • HTTP ステータスコードに割り当ててレスポンスとして作成
  • 28. テスト • Model や共通関数などはテストを作っておく • 実際に処理させてチェックだと面倒 • テストに合わせて daemon を起動するようにしてあげると良い • http://perl-users.jp/articles/advent-calendar/2011/test/18 • テストを書きすぎるとキリが無くなってしまうのでバランス大事 • Jenkins などの CI ツールをうまく活用 • API はレスポンスのテストしやすい • JSON なので期待値との比較などが容易 • Test::WWW::Mechanize::PSGI などを活用
  • 29. 環境ごとの切り分け • Amon2 の機能で config を切り替えられる • 接続先ホストやユーザ名などを変えておく • 開発時だけ環境変数でフラグを入れたりすると便利 • 本番と開発環境でドメイン + 階層が異なってもうまく吸収できる • 同一ドメインで全てをサーブしたい場合はまとめた psgi を作ってたてる # app.psgi ... builder { mount '/api/' => Plack::Util::load_psgi('api.psgi'); mount '/admin/' => Plack::Util::load_psgi('admin.psgi'); }; • 異なるドメインの場合は個別にプロセスをたてる • Proxy などでわけてアクセスできるようにする
  • 30. 本番環境 • Starman + Server::Starter $ carton  exec  -­‐-­‐  start_server  -­‐-­‐port=5000  -­‐-­‐signal-­‐on-­‐hup=USR1  -­‐-­‐   plackup  -­‐s  Starlet  -­‐-­‐spawn-­‐interval=5 • プロセスを supervisord で立ち上げる • 標準出力のログは supervisord がファイルに書き出してくれる • ローカルに Nginx をたててローカルの Starman に送る • Nginx 側でアクセスログを取得 • 管理画面のアクセス制御や多段 Proxy 時のヘッダコントロールなど
  • 31. 連携 Cooperation
  • 32. クライアントアプリとの連携 • iPhone を例にいくつか紹介 • Objective-C 的な話も出てきますが軽く触れるだけにします • AFNetworking (https://github.com/AFNetworking/AFNetworking) • AFJSONRequestOperation で JSON -> NSDirectory と変換 • NSDirectory で init できるようにデータオブジェクトを定義しておく • オブジェクトが入れ子になっているようにしておく • このクラスがあるから、API の出力も同じようにできるオブジェクトを考 えてるわけで
  • 33. API のコールと JSON 値の変換 • 1回のリクエストで階層化したデータを返せるようにする • 通信回数を抑えることが大事 • 画面遷移の度に通信を発生させたくない • 海外を見据えてるなら通信環境が優れている場所ばかりとは限らないため • 値を変更したらその変更を通知して画面も更新する必要がある • インターフェイスとのバランスも考える必要がある • 送信 ボタンがあるとは限らず、トリガスイッチだけだったりもする • アプリ開発者と連携しながら相互に調整する必要がある
  • 34. リクエストヘッダ • 独自のユーザエージェントを設定 • 独自の HTTP ヘッダをアプリからの通信時に埋め込む • クライアントアプリのバージョン • X-LiteSNS-Version • ユーザの閲覧環境 • X-LiteSNS-Locale • X-LiteSNS-Language • X-LiteSNS-Timezone • このあたりはアプリサイドのコードで埋め込むことができる • ルールを決めておくことが大事
  • 35. APNS を用いた PUSH 通知 • Apple Push Notification Service (APNS) • 詳細は iOS Developer Library を参照 • 通知の流れ 1.アプリでデバイストークンを取得してサーバに送信 • NSData を16進数などに変換してサーバに POST 2.サーバサイドでアクティブなセッションと紐づけて保持しておく 3.モジュールを利用して通知パケットを APNS サーバに送る • Net::APNS, AnyEvent::APNS • AnyEvent::APNS の例は typester さんの解説が分かりやすいです • http://perl-users.jp/articles/advent-calendar/2010/hacker/7
  • 36. -­‐(void)applicationDidFinishLaunching:(UIApplication  *)application   {                //  初回起動時に  「“LiteSNS”はあなたにプッシュ通知を..」  という確認ダイアログを表示        [[UIApplication  sharedApplication]  registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert  |  UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; } -­‐  (void)application:(UIApplication  *)app  didRegisterForRemoteNotificationsWithDeviceToken: (NSData  *)deviceToken   {          //  ここで  NSData  形式の  deviceToken  を16進数変換して送ります } use Net::APNS; my $APNS = Net::APNS->new; my $notification = $APNS->notify({ cert => ‘path/to/app.cer’, key => ‘path/to/app.key’, }); $notification->devicetoken(‘device_token’); # ここで16進数のトークンをセットする $notification->message("new message from LiteSNS"); # 通知メッセージ本文 $notification->badge(1); # アプリアイコンにつけるバッジの数 $notification->write;
  • 37. まとめ Summary
  • 38. まとめ • 設計 • 見えるところから見えないところへと考えを掘り下げていく • 最初に全てを決めきれないので、作りながら微調整は必要 • 開発 • 仕組みを考えながら組み合わせて作っていく • スケールする仕組みをあとからでも入れられるようにする • 連携 • ライブラリをうまく使ってデータを組み立てていく • スマートフォンならでは、アプリならではの視点も必要
  • 39. まとめ • やってみて分かったこと • 様々な観点が必要とされている • プログラム、ミドルウェア、に加えてフロント側も • 特性とかユーザの利用シーンもちゃんと考えないとうまく作れない • でも、難しいことではない • (本来は)全部を一人でできなくてもいい • タスクを振るとき、全体を設計するときにあると良い • 何ができるか、を知っていることが大事 • Titanium など敷居の低い開発手法もあるので試してみるのが良い