今まではネイティブのクライアントへJsonでレスポンスを返していたのですが、新しいサービスを開発する際に、レスポンスをMessagePac
ちなみにリクエストまでMessagePac
検証用アプリ
構成は下記の通りです。
- Nginx
- Passenger
- Ruby2.0
- Rails4
今回の検証はJson圧縮とMessagePac
(参考) JSONの替わりに使ったOJが速い
(参考) MsgpackRai
1 gem 'oj' 2 gem 'msgpack-rails', :git => 'git://gith ub.com/nzi fnab/msgpa ck-rails.g it'
Controller
1 class StaticPagesControlle r < Applicatio nControlle r 2 3 require 'oj' 4 5 after_acti on :testcompre ss 6 7 respond_to :json, :mpac 8 9 SERIALIZE_ TEST_RESPO NSE = {(省略)} 10 11 def serialize_ test 12 respond_to do |format| 13 format.json { render :json => SERIALIZE_ TEST_RESPO NSE } 14 format.mpac { render :text => SERIALIZE_ TEST_RESPO NSE.to_msgpack , :content_ty pe => 'applicatio n/x-mpac' } 15 end 16 end 17 18 def testcompre ss 19 response.body = ActiveSupp ort::Gzip.compress(response.body) 20 end 21 22 end
- oj が追加されていると、MultiJSONによって自動的に oj が選択されるようです。
- シリアライズするHashデータを SERIALIZE_
TEST_RESPO NSE として定義しておきます。 - 処理内容としてはテスト用のデータをシリアライズして返すだけです。
- また、今回はシリアライズ+圧縮を試すのですが、Rails側で圧縮した場合と、Nginxで圧縮した場合も比較してみます。Rails側で圧縮する場合の処理を testcompre
ss メソッドに定義しておいて、after_acti on で gzip 処理を行います。Nginx側で圧縮する場合は after_acti on をコメントアウトします。
検証方法としては、JMeterサーバを3つ用意して、100スレッドから上記APIへかけられるだけ負荷をかけてみるというやり方です。Nginxで圧縮するケースではHTTPヘッダマネージャでAccept-Enc
1 gzip_typestext/plain text/css applicatio n/json applicatio n/x-javasc ript text/xml applicatio n/xml applicatio n/xml+rss text/javas cript applicatio n/x-mpac;
デフォルトでは applicatio
検証結果
検証結果は下記の通りです。
種別 | 圧縮 | サンプル数 | 平均 | 中央値 | 90%LINE | 最小値 | 最大値 | スループット | KB/sec |
---|---|---|---|---|---|---|---|---|---|
Json | Rails | 48626 | 1816 | 1805 | 2002 | 25 | 2258 | 158.57 | 306.30 |
MessagePac | Rails | 271372 | 317 | 321 | 356 | 5 | 533 | 889.05 | 1701.66 |
Json | Nginx | 48824 | 1785 | 1775 | 1988 | 27 | 2206 | 159.11 | 393.07 |
MessagePac | Nginx | 333783 | 249 | 248 | 279 | 4 | 466 | 1093.61 | 2395.42 |
MessagePac | 非圧縮 | 346175 | 246 | 246 | 271 | 6 | 610 | 1134.33 | 19178.19 |
Jsonの場合はCPUは常に振り切っている状態でしたが、MessagePac
テスト結果のスループットとしてはMessagePac