2014-08-31

YAPCに行ってきた

YAPCに行ってきました。Perlのセッションを避けたつもりは無かったのですが、モバイルアプリ開発やデータ分析のセッションに出ていたらほとんどPerlの話はありませんでした、適材適所というか、普段Perlを書かない人間には参加の敷居がどんどん下がっている印象。

Google BigQuery で DWH 構築

BigQueryといえばGoogle Analyticsのプレミアムプランの印象が強くて、100万JPY/month払って使う物と考えていたが。自前DWHのストレージとして使うととても安く、どんなクエリでも高速に帰してくれる奴だと知った。今丁度データ分析プラットフォーム構築業をしているので、休み明けにでも検証したい。
https://speakerdeck.com/naoya/google-bigquery-falsehua-number-yapcasia

JSON SQLインジェクション脆弱性と、そこから学ぶセキュアプログラミングの原則

構造化されたクエリパラメータをパースできるようなおしゃれなWebアプリケーションフレームワーク、使ってみたいと思った。

そんなにビッグでもないデータ処理手法の話

fluentdの圧倒的人気。この分野は自分が素人なので、どんなミドルウェアがあるのか知れたのはよかった。BigQuery等の登場によりデータ保持コストとコンピューティングリソースコストがこのまま下がり続けると、サンプリング調査や信頼区間といった統計的な手法を忘れて常に全数調査で良くなる、みたいな話をHUBでssig33とした。
http://www.slideshare.net/tagomoris/handling-not-so-big-data

モバイルアプリとAPIのありかたを考える2014

良く見る画面だなと思ったらParse.comのデモだったり。
JSON-RPCのバッチリクエストの話は、これはシンプルさを捨ててパフォーマンス(バッテリー効率、処理速度)を取るというアプローチなので、モバイルアプリなら全然ありかなと思った。

curlでターミナルから打つのが大変になる等のデメリットはあるが、クライアントが任意にリクエストを一つに纏められるというのが大きい。アプリ起動時だとユーザーのステータスやイベントの有無を取得したり複数のAPIを叩くというのはよくあるし、バッテリー効率を考えたらユーザーの操作ログみたいな物は纏めて送れた方がいい。サーバー側の設計の話はあまり無かったけど、APIコールのコストをけちって、貪欲なレスポンスを返さなくても良いので、サーバーAPIの粒度を小さくできるのもメリットかな。

あと、この話を聞いてる最中に自前ライブラリのバッチリクエスト対応をした。

Mobile Application Development for Perl Mongers [ninjinkun x gfx]

いい話だった。アプリ開発にgit-flowを使うの、仕様フリーズしてQA期間がありつつも次のバージョンの開発もする場合は確かにそうだなと。MVVM重要、Reactive Cocoaは後でチェックする。

その他

YAPCサイトのトークスケジュールの画面、iPhoneから見ると [ビギナー]とか[レギュラー]の難易度表示が無いの、罠だった。
大学内にHUBがあるのやばい。

まとめ

CONBUとスタッフの皆さんありがとうございました。



このエントリーをはてなブックマークに追加

2014-08-30

jquery-jsonrpc2.0のバッチリクエストとPromise対応

オレオレJSON-RPCライブラリがバッチリクエストに対応していなかったので対応した。こんな風に書けるようになった。
$.jsonrpc.defaultUrl = '/rpc';

// Send 3 requests at once.
$.jsonrpc([{
    method: 'getEventStatus'
}, {
    method: 'getUserStatus'
}, {
    method: 'sendLoginStatus',
    params: {status: 'login'}
}]).done(function(responses) {
    results.forEach(function(response) {
        if (response.result) {
            doSomething(response.result);
        } else {
            handleError(response.error);
        }
    });
}).fail(function(error) {
    // timeout or 503 or bad response
});
なぜ今になってメンテしたかというと、モバイルアプリはクライアントが任意に複数のAPIコールを一つのHTTPリクエストに纏められた方が良いよねと最近思う様になった*1 のと、今日のYAPCのセッションでJSON-RPCのバッチリクエストについて説明があったので。YAPCの感想はまた次のエントリで。

あとbowerのリポジトリを眺めていたら、WebSocketを使う物を見つけたのでこちらの方がおすすめです。

脚注:
*1: Orreily「ハイパフォーマンスブラウザネットワーキング」の影響

このエントリーをはてなブックマークに追加

2014-08-04

ハイパフォーマンスブラウザネットワーキング輪講を社内でやっている話

ハイパフォーマンス ブラウザネットワーキング ―ネットワークアプリケーションのためのパフォーマンス最適化ハイパフォーマンス ブラウザネットワーキング ―ネットワークアプリケーションのためのパフォーマンス最適化
Ilya Grigorik,和田 祐一郎,株式会社プログラミングシステム社

オライリージャパン
売り上げランキング : 94924
Amazonで詳しく見る by AZlink
O'rreilyのハイパフォーマンスブラウザネットワーキングは日本語版が発売されたのを機に輪講形式で社内勉強会をやっている。先週の時点で8章の「モバイルネットワークの最適化」が終り、丁度折り返し地点である。

なぜ輪講形式にしたか

本の内容は、光ファイバーや無線の規格といった下のレイヤからHTTP2やWeb RTCの上のレイヤまでカバーしている。その範囲からして、アプリケーションエンジニアだけでやるよりも、インフラの人に解説してもらった方が面白いのでは、と思ったから。

例えばTLSの章に出てくる証明書チェーンの最適化のくだり、インフラとアプリで分業が進んでいるとアプリエンジニアは運営しているサービスの証明書チェーンがどうなっているかなんて意識していないだろう。TCP最適化の所には「サーバーは最新のカーネル使え」とあるがフロントのエンジニアにはどうしようも無い。本に載っているテクニックが採用可能かといった議論するには各分野に詳しい人がいた方が良い。

モバイルアプリ開発者が読んで得られる事

今の時点で書ける所を。特に5章から8章はモバイルアプリ開発者には面白いはず。TCPやUDPは他にいくらでも本はあるが、アプリ開発者向けに無線技術、モバイルネットワークの解説があるのは本書ならでは。

例えば自分の場合

  • 移動していれば接続基地局は切り変わるはずだが、TCPのレイヤで見るとサーバーと繋がったままに見えるのはなぜか
  • モバイルアプリでもGeoIPで良い感じに端末のいる都市が取れるのはなぜか
  • 位置情報を送り続けるアプリを適当に実装すると、あっという間にバッテリーを食いつくすのはなぜか

といった前からの疑問が解決した。バッテリーを無駄に消費しないためには、実際にどう実装すれば良いのかという知見と失敗例は参考になる。

あと、WebRTCに入門してみると必ず出てきて、ネットワーク初心者に混乱をもたらすSTUNやTURNなる謎のワードも前半のNATの章に解説がある。XMLHttpRequest等のブラウザに特化した話は後半になるまで出てこないが、いきなり後半をやるよりも最初から目を通していくのが良いと感じた。

普段なにげなく使ってはいるが中身の動作は知らなかった、という部分がどんどん埋められていく感覚が気持ちいい。

まとめ

カバーしている範囲が広いだけに、アプリ、セキュリティ、インフラ各々得意な分野が異なる人で集まって議論すると面白い。
後半もがんばるぞいという事で、参加者の皆様もいつもありがとうございます。

このエントリーをはてなブックマークに追加

2014-06-30

アプリケーションエンジニアとサーバープロビジョニングツール

自分はサーバープロビジョニングといえば、AWS上の本番・ステージング・共有開発機もろもろインフラチームにまかせっきりだった。しかしアプリエンジニアがローカル開発環境を作る用途ならChefやPuppetよりもAnsibleがマッチしていると思った次第。

背景

自分の職場だと、インフラチームはPuppetのマニフェストでサーバーを管理している、例えばサーバーにインストールするパッケージ やApacheの設定である。しかし、そのPuppetマニフェストはアプリエンジニアのローカルの環境を構築する用途としてそのまま使えない。

インフラチーム管理下のサーバーにおいてPuppetマニフェストで管理されている部分はアプリケーションエンジニアは触れないため、変更を加えたい場合は都度依頼を出している。

共有開発サーバーとローカル個人環境

例えばApacheとfluentdとElasticsearchはインフラチームが管理しており、KibanaでApacheログが見れるとしよう。Kibanaに思った通りのグラフが出せない時、自由にできる環境がなければどこをいじれば良いのか試行錯誤すらできない。必然的に共有開発サーバーではなく、個人環境が欲しくなる。

Ansibleを使ってみる

ここで欲しいのは、Apacheログがfluentdに回収されてElasticsearchに放りこまれてKibanaで見られる環境をコマンド一発で作れる何かである。Chefでも良かったが、もっと気軽に使える物は無いかとAnsibleを試してみた。

結果、作成が必要だったのは対象のサーバーを指定するファイルとレシピに相当するyamlファイル、コピーして配置する用の設定ファイル(httpd.conf等)だけで済んだ。至って簡潔。しかも対象サーバーにPython 2.4以上さえ入っていれば使える。

リポジトリには起動用のMakefileとREADMEを追加してコミットしておけば良い。

サーバープロビジョニングツールについて

インフラチームが使う高機能な物と、アプリケーションチームが使う簡易な物、それぞれ別の物が流行ると思う。少なくともChefは二度使った経験からすると、使い方とレシピの書き方を思い出すのが面倒すぎる。

ちなみに、本エントリの例題構成をプロビジョニングするAnsibleのPlaybookは次の通りになった。わかりやすい。
- hosts: webserver
  user: vagrant
  sudo: yes
  tasks:
    # Apache
    - name: Install apache
      apt: name=apache2 update_cache=yes
    - name: Copy /etc/apache2/apache2.conf
      copy: src=./settings/apache/apache2.conf dest=/etc/apache2/
    - name: Restart apache
      service: name=apache2 state=restarted

    # Elasticsearch
    - name: Get apt key for elasticsearch
      apt_key: url=http://packages.elasticsearch.org/GPG-KEY-elasticsearch
    - name: Add apt repository
      apt_repository: repo='deb http://packages.elasticsearch.org/elasticsearch/1.1/debian stable main'
    - name: Install JDK
      apt: name=openjdk-7-jre-headless update_cache=yes
    - name: Install elasticsearch
      apt: name=elasticsearch update_cache=yes

    # Elasticsearch Plugins
    - name: Remove elasticsearch-head
      command: /usr/share/elasticsearch/bin/plugin --remove mobz/elasticsearch-head
    - name: Install elasticsearch-head
      command: /usr/share/elasticsearch/bin/plugin --install mobz/elasticsearch-head
    - name: Remove elasticsearch-kibana
      command: /usr/share/elasticsearch/bin/plugin --remove elasticsearch/kibana3
    - name: Install elasticsearch-kibana
      command: /usr/share/elasticsearch/bin/plugin -url http://download.elasticsearch.org/kibana/kibana/kibana-latest.zip --install elasticsearch/kibana3

    - name: Restart elasticsearch
      service: name=elasticsearch state=restarted

    # td-agent
    - name: Get apt key for treasure-data
      apt_key: url=http://packages.treasure-data.com/debian/RPM-GPG-KEY-td-agent
    - name: Add apt repository
      apt_repository: repo='deb http://packages.treasure-data.com/precise/ precise contrib'
    - name: Install td-agent
      apt: name=td-agent update_cache=yes

    - name: Install libcurl-dev
      apt: name=libcurl4-openssl-dev update_cache=yes
    - name: Install plugin
      command: /usr/lib/fluent/ruby/bin/fluent-gem install fluent-plugin-elasticsearch

    - name: Copy td-agent.conf
      copy: src=./settings/td-agent/td-agent.conf dest=/etc/td-agent/
    - name: Restart td-agent
      service: name=td-agent state=restarted

まとめ

Ansibleはアプリエンジニアに向いている、というのと。以前、@voluntasの人に「御社はAnsibleやDockerを使って開発環境を作れるようにしてないんですか?」とつっこまれたのだが、これからはちゃんとできそうだ。

このエントリーをはてなブックマークに追加

2014-05-14

iOS Push通知配信サーバーのコネクション管理

前回のエラーハンドリングの話に続いてコネクション管理について。今どきPush通知配信サーバーを自前で用意する事は少ないかもしれないけど、そういう人向けの内容。

コネクションの管理

APNsのドキュメントにこうしろと書いてある。
Best Practices for Managing Connections

You may establish multiple connections to the same gateway or to multiple gateway instances. If you need to send a large number of push notifications, spread them out over connections to several different gateways. This improves performance compared to using a single connection: it lets you send the push notifications faster, and it lets APNs deliver them faster.

Keep your connections with APNs open across multiple notifications; don’t repeatedly open and close connections. APNs treats rapid connection and disconnection as a denial-of-service attack. You should leave a connection open unless you know it will be idle for an extended period of time—for example, if you only send notifications to your users once a day it is ok to use a new connection each day.

Local and Push Notification Programming Guide: Provider Communication with Apple Push Notification Service
つまり
  • 通知毎に接続をOpen/Closeするな、APNsはそれをDoSと扱う
  • Openしたまま維持しろ
  • 大量に配信したい場合は複数接続を張るといいよ
  • 1日に一回送るぐらいなら、その度に新しく接続を作ってもいいよ
 となるので、この通りに実装する。Webサーバーでユーザーからのリクエストをトリガーにして送るとその度にOpen/Closeになる、よってユーザー間等の通知を頻繁に送るアプリの場合はアプリケーションサーバーから通知配信処理のプロセスを分離する方式になるかと。

Gateway Serverからエラーレスポンスが返ってきた場合、向うから接続を切ってくる。その時は新しい接続を作る。

apns-proxy-serverでもスレッド毎にGateway Serverとの接続を持つようにして、接続の維持と並列化を実現している。

原因不明のBroken Pipeエラー

データフォーマットのエラーや、Invalid Tokenエラーとは関係無く、Broken Pipeに遭遇する事がある。Gateway Serverがなんらかの理由でコネクションを切るからだと思われるが、こちらとしては接続を張りなおして、送ろうとした通知からリトライするぐらいしかやれる事は無い。


このエントリーをはてなブックマークに追加