Gaurun〜A general push notification server in Go〜
Go Conference 2015 Summerでトークが採択されたこともあるので、自分が所属している会社で開発しているプッシュ通知サーバであるGaurunをOSSで公開しました。詳しくは2015年6月21日開催のGo Conference 2015 Summerで・・・というのもアレなので軽くGaurunについて紹介します。
メルカリのプッシュ通知システムの構成と変遷
昨年9月にメルカリに入社した当時、メルカリのアプリ内で発生したイベントのプッシュ通知処理はすべてPHPで書かれたAPIサーバ上で**同期処理(!)**として実装されていました。例えばAPIサーバにコメント書き込みのリクエストが来たらコメントのデータをDBに書き込んだ後プッシュ通知を行ってクライアントにレスポンスを返す、という具合にです。
当然のことながらスマートフォンアプリでよく利用されるAPNSやGCM(あるいはAmazon SNS)によるプッシュ通知は外部サーバとの通信を伴うため非常に時間がかかります(数百msecから数sec)。実際、当時Treasuredataでアクセスログに記録されているレスポンスタイムを降順に集計するとプッシュ通知のイベントが発生する可能性のあるAPIが上位を占めていました。
php-Parallel-PreforkとQ4Mによる非同期プッシュ通知
そこで私が入社して最初にやった仕事がphp-Parallel-PreforkとQ4Mを利用してこの部分を非同期で行うようにしたことでした。幸い既にそのためのフレームワークが整備されていたので、これは比較的簡単に実施でき、またAPIサーバのパフォーマンス向上に対して大きな効果がありました。
これから数百万件のプッシュ通知送りたいんだけど・・・
アプリ内で発生したイベントのプッシュ通知の数自体は全体のリクエスト数と比べるとあまり多くありません。一方でキャンペーンやユーザへのお知らせ等で瞬間的に大量のプッシュ通知を実行するというタスクが時々発生します。それこそいきなり「これから数百万件のプッシュ通知送るけどいい?」とか。
この問題に対して当初はphp-Parallel-Preforkを起動したサーバをたくさん並べて対処していましたが、これはあまりパフォーマンスが良くなくてスケールしませんでした。
nginx + Go(net/http)による汎用プッシュ通知システム
大量プッシュ通知処理をスケールさせるにはプログラムに高い並行性が要求されるのでそもそもPHPには不向きなタスクです。そこでGCMとAPNSへのプッシュ通知処理を独自のAPIでラップしてプロキシするHTTPサーバをGoで書き、前段にnginxを配置してロードバランシングする構成にしました。このHTTPサーバが後のGaurunです。
結果的にこの構成にすることで大量のプッシュ通知処理を簡単にスケールすることができるようになりました。また、APNSやGCMとのキープアライブやそれぞれのプロトコルの違いについてもクライアント側では特に意識する必要もなくなり、プログラムロジックが簡略化されるといった副次効果もありました。
Gaurun事始め
続いてGaurun自体の簡単な紹介です。
Gaurunのダウンロードとビルド
今のところGaurunのビルド済みバイナリは配布していないので実行するには別途Goの環境を用意してコンパイルする必要があります。
$ git clone https://github.com/mercari/gaurun.git
$ cd gaurun
$ make gom
$ make bundle
$ make
Gaurunの起動と設定ファイル
Gaurunを起動するにはTOMLによる設定ファイルが必要です。
$ bin/gaurun -c conf/gaurun.toml
設定ファイルの詳細はCONFIGURATION.mdにまとまっています。
HTTP API
Gaurunには以下の4つのAPIがあります。詳細はSPEC.mdにまとまっています。
API名 | 解説 |
---|---|
POST /push | プッシュ通知リクエストを受付 |
GET /stat/go | Goランタイムのモニタリング用データ取得 |
GET /stat/app | Gaurunのモニタリング用データ取得 |
GET /config/app | Gaurunの設定データ取得 |
クライアントのサンプルプログラム
Gaurunサーバにプッシュ通知のリクエストを送るためのクライアントプログラムのサンプルがあります。
さいごに
今回は非常に簡単な紹介に留めましたが、Go Conference 2015 Summerではもう少し詳しく突っ込んだ話をしようかと思います。