F@N Ad-Tech Blog

株式会社ファンコミュニケーションズ nend・nex8・viidleのエンジニア・技術ブログ

ScalaのSくらいしか知らなかったモバイルアプリエンジニアですが、はじめてサーバーをつくりました

こんにちは、はじめましての方々ははじめまして。
3月5日〜3月9日まで1週間のインターンという形でお世話になりました。とやまです。

タイトルにもある通り今まで僕はAndroidのアプリ開発を中心に行ってきたいわゆるモバイルアプリエンジニアですが、Scalaへの興味とバックエンドエンジニアリングというまだ見ぬ領域について知りたくて今回のインターンに参加させていただきました。

その参加レポートを書かせていただきます。

1週間でやったこと

Play frameworkとFinagle(Finch)を使ったSSPの構築

1日目

 1日目はアドテク業界とアドテクサーバーの仕組みについて少し教えていただいた上で1週間のテーマを選定、その後ドワンゴ様が提供しているScala新卒研修テキストを頼りにScalaをおさらいしました。
聞いたところ、社内にはDSPに携わる方々は多い中、SSPに携わっている方は少ないこともあって、SSPを異なるフレームワークやライブラリを使ってベンチマークをする人がいなかったとのことです。
Scalaもあまり知らない上、アドテクについても全く知らなかったけど、せっかくインターンに参加するならわずかでも会社の役に立ちたいと思ってこのテーマをやらせていただきました。ちなみに、今回のSSPとDSPの実装仕様は以下のissueにあります。

github.com

2日目

 2日目は早速Play frameworkを使ってSSPを作ることからはじめました。
半日使ってそれっぽいものを作っていた感じはしていたのですが、僕が半日かけて作っていたものはHTTPサーバーではなく、ソケットサーバーだったことを1日のほぼ終わりどきに気づいて頑張って作り直しました。
最初は「やらかした」と思っていましたが、今となってはそれぞれの仕組みついて両方理解することができたので逆によかったなと感じます。

3日目

 3日目は、前日のPlayサーバー開発の続き、超簡易型DSPの開発を行いました。淡々とPlayとScalaを知るだけでなく、Scalaらしい関数型としての書き方も教えていただきました。特にfor式とyieldを使ったfor内包式のすばらしさにはとても感動しました。なるほど、mapやflatMapはこうやって実現できているのかと。改めてScalaの素晴らしさを思い知らされた1日でした。

4日目

 4日目はPlayサーバーのベンチマークテストとFinagleサーバーの開発を行いました。ベンチマークの結果についてはこの後書きます。
Finagleはそのまま使うのではなく、基本的にそのラッパライブラリを使うものだと聞いたのでFinchを使って実装を行いました。
はじめFinchを触って感じたことは、Playよりも応用がきいたライブラリなのか色々コードの自由度が高いなと感じました。JsonのパースもPlayの時のような最初からパーサーが付属されている感じではなく、circeなどのパーサーライブラリを使わなければならないことも自由度が高いと感じる部分でもありました。関数型に実装を近づけるならFinchだとということがよく分かりました。

5日目

 5日目はFinagleサーバーの実装をギリギリまでしました。本当はこのブログも最終日に書かなければいけなかったのですが、僕のムチャブリで後日提出する形にさせてもらいました。ありがとうございます。
褒められるほど綺麗なコードとまではいきませんでしたが、動くものが完成してベンチマークも行いました。最後はキリの良いところで終わることができたので良かったです。

1週間の成果

今回作成した2つのサーバーは僕のGithubにあげました。以下になります。

github.com

github.com

Finagleサーバーのベンチマークは後日酒井さんがプルリクエストを送っていただきました。

$ h2load -p http/1.1 -H Content-Type:application/json -d sample.json -c 100 -n 1000 http://localhost:9000/v1/ad
starting benchmark...
spawning thread #0: 100 total client(s). 1000 total requests
Application protocol: http/1.1
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 4.75s, 210.64 req/s, 30.79KB/s
requests: 1000 total, 1000 started, 1000 done, 859 succeeded, 141 failed, 0 errored, 0 timeout
status codes: 859 2xx, 0 3xx, 141 4xx, 0 5xx
traffic: 146.17KB (149681) total, 81.94KB (83911) headers (space savings 0.00%), 29.36KB (30065) data
                     min         max         mean         sd        +/- sd
time for request:    15.70ms       2.38s    363.72ms    654.46ms    89.90%
time for connect:      546us      4.49ms      2.50ms      1.02ms    60.00%
time to 1st byte:      2.25s       3.13s       2.43s    144.92ms    72.00%
req/s           :       2.11        3.10        2.75        0.14    88.00%

また、Playサーバーのベンチマークです。

$ h2load -p http/1.1 -H Content-Type:application/json -d sample.json -c 100 -n 1000 http://localhost:9000/
starting benchmark...
spawning thread #0: 100 total client(s). 1000 total requests
Application protocol: http/1.1
progress: 10% done
progress: 20% done
progress: 30% done
progress: 40% done
progress: 50% done
progress: 60% done
progress: 70% done
progress: 80% done
progress: 90% done
progress: 100% done

finished in 1.84s, 542.53 req/s, 203.50KB/s
requests: 1000 total, 1000 started, 1000 done, 1000 succeeded, 0 failed, 0 errored, 0 timeout
status codes: 2 2xx, 998 3xx, 0 4xx, 0 5xx
traffic: 375.09KB (384096) total, 302.77KB (310038) headers (space savings 0.00%), 88B (88) data
                     min         max         mean         sd        +/- sd
time for request:     5.19ms    615.94ms    172.32ms    110.00ms    78.40%
time for connect:      364us      6.84ms      3.37ms      1.91ms    57.00%
time to 1st byte:   128.61ms    146.79ms    137.70ms     12.86ms   100.00%
req/s           :       5.43        6.84        5.81        0.38    83.00%

確実な結果ではありませんが、Finagleで実装したサーバーの方が早そうです。

最後に

1週間と短い間でしたが、メンターとしてテーマやScalaについて真摯に教えてくださった酒井さん、他社員のみなさんありがとうございました。
初めてのScala、初めてのサーバーサイドでかなり苦労しましたが、多くのことを学ぶことができました。
また、アドテク業界の奥の深さについても知ることができて、この業界の興味がとても湧きました。
今後は自分でもっとScalaやデファクトスタンダードであるCatsについて勉強してしていくことで関数型についての学習を深めていきたいと思います。