Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

H2O x mrubyで人はどれだけ幸せになれるのか

10,082 views

Published on

YAPC::Kansai presentation slide about h2o and mruby

Published in: Engineering
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

H2O x mrubyで人はどれだけ幸せになれるのか

  1. 1. Copyright © DeNA Co.,Ltd. All Rights Reserved. H2O x mrubyで ⼈はどれだけ 幸せになれるのか March 4, 2017 @i110 Technology Development, System Management Unit DeNA Co., Ltd. YAPC::Kansai 御中
  2. 2. Copyright © DeNA Co.,Ltd. All Rights Reserved. ⾃⼰紹介 !  @i110 !  株式会社ディー・エヌ・エー !  システム本部技術開発室所属 ⁃  ⾊んな⼈が⾊んなことをやってる部署 ⁃  平均年齢⾼め !  昨年夏くらいにあれやこれやあってH2Oの開発にjoin !  現在、業務時間の全てをH2Oの開発に注いでいる状態 ⁃  最近はmrubyまわりの機能追加&改善が多め 2
  3. 3. Copyright © DeNA Co.,Ltd. All Rights Reserved. H2Oについてさらっと 3
  4. 4. Copyright © DeNA Co.,Ltd. All Rights Reserved. H2Oとは !  https://h2o.examp1e.net/ !  Google翻訳いわく !  おおむねこの通りです(⾚字部分を除いて) !  みんな⼤好き某kazuho sanが開発 !  現在の最新verはv2.2.0-beta1 4 H2Oは、古い世代のWebサーバーと⽐較して、 CPU使⽤率が低いユーザーに迅速な応答を提供する、 新しい世代のHTTPサーバーです。 基盤から設計されたサーバーは、優先コンテンツ配信と サーバープッシュを含むHTTP / 2機能をフルに活⽤し、 Webサイトの訪問者に有望な経験を提供します。
  5. 5. Copyright © DeNA Co.,Ltd. All Rights Reserved. H2Oはなぜ⾼速なのか !  主に3つの理由による 1.  優先度制御が優秀 2.  先進仕様への対応の速さ(Cache-digests、TLS1.3、etc..) 3.  neatかつ無駄のない実装 !  詳しくはWebで! 5
  6. 6. Copyright © DeNA Co.,Ltd. All Rights Reserved. しかし… !  Apacheとnginxつよい !  理由(私⾒) 1.  豊富なモジュール群 2.  情報の多さ 3.  枯れてる度 !  私は当然H2Oが最⾼のWebサーバーだと信じているので 世界の⼈々をより幸せにするためにH2Oが普及してほしい !  速いことはわかった。それ以外に何が必要か 6 hGps://w3techs.com/technologies/overview/ web_server/all
  7. 7. Copyright © DeNA Co.,Ltd. All Rights Reserved. 便利で快適なWebサーバーへ !  Apacheやnginxに出来て、H2Oに出来ないことを無くしたい !  拡張モジュールの整備 !  ユーザー⾃⾝による拡張モジュールの書きやすさ !  Apacheやnginxよりも、同じことが簡単にできるようにしたい !  設定ファイルの柔軟さ&テスタビリティ !  あとドキュメントももっと沢⼭書きますすいません 7
  8. 8. Copyright © DeNA Co.,Ltd. All Rights Reserved. 組み込み⾔語としてのmrubyの採⽤ !  2015年7⽉にリリースしたv1.4で、 Ryosuke Matsumoto(@matsumotory) さんが初期実装 !  リクエストハンドラとしてmrubyのコードを実⾏できる 8
  9. 9. Copyright © DeNA Co.,Ltd. All Rights Reserved. 組み込み⾔語としてのmrubyの採⽤ !  ApacheやNginxよりも強いサポート !  コアに付属、デフォルトでON !  ⾮同期I/Oを可能にする各種ライブラリの提供 !  Rack Specに準拠した⾃然なインターフェース !  今後さらに⼿厚くしていく予定 !  想定⽤途 !  アクセス制御、URIリライト、レスポンスの書き換え、etc.. !  プログラマブルで柔軟な設定が可能に !  サーバー機能の⼿軽な拡張も可能に 9
  10. 10. Copyright © DeNA Co.,Ltd. All Rights Reserved. mrubyの何がどう嬉しいのか 1.  サーバ機能の拡張性 2.  設定の柔軟性&テスタビリティ 10
  11. 11. Copyright © DeNA Co.,Ltd. All Rights Reserved. 1. サーバ機能の拡張性 !  ユーザ⾃⾝が、欲しい機能をさくっと書いて追加できる状態が理想 !  しかしcでモジュール作るのは⼤変 !  Cloudbleed (2017) !  https://blog.cloudflare.com/incident-report-on-memory-leak-caused-by-cloudflare- parser-bug/ !  Cloudflare (CDN)で発⽣したユーザ秘匿情報の漏えい問題 !  原因は、内製のnginxモジュール(HTMLパーサ)のバグ !  ポインタ管理のミスによるバッファオーバーラン !  mrubyで書けば原理的に発⽣しえない問題 !  コードにバグがあっても、バッファオーバーランが発⽣することはない 11
  12. 12. Copyright © DeNA Co.,Ltd. All Rights Reserved. 2. 設定の柔軟性&テスタビリティ !  個⼈的な話にはなりますが、Apacheやnginxのディレクティブを ⼀切覚えられない(覚えるつもりもない)ので 毎回サーバー⽴てるたびに2時間くらいぐぐっている !  凶悪なmod_rewrite、 ミスりやすいアクセス制御、 何故か効かないsection… !  理想 !  シンプルなことはディレクティブで簡単に !  複雑なことはプログラマブルにがっつり 12
  13. 13. Copyright © DeNA Co.,Ltd. All Rights Reserved. なんとなく印象と⼀致する参考値 !  ⽐較 !  Excel not working: 1,170万件 !  PowerPoint not working: 1,040万件 !  nginx config not working: 73万件 !  nginxはユーザーの⾃⼰解決能⼒が⾼いというのもありそう 13
  14. 14. Copyright © DeNA Co.,Ltd. All Rights Reserved. 2. 設定の柔軟性&テスタビリティ !  ディレクティブによる設定だと、設定がちゃんと効いているか 実際にリクエストを送って試してみるしかない !  設定追加したらConflictして別の箇所が動かなくなった!とか… !  複雑であるからこそテストを書きたいのに… !  mrubyならテストを書ける !  粒度の細かい単体テスト !  スタブを使ったテスト !  etc.. !  近⽇中に何かしらのHowToを公開します(たぶん) 14
  15. 15. Copyright © DeNA Co.,Ltd. All Rights Reserved. というわけで、本⽇は !  H2O x mruby の仕組みの簡単な解説 !  知られざる機能の紹介 !  ステルスで追加した機能 !  近々マージ予定の機能 15
  16. 16. Copyright © DeNA Co.,Ltd. All Rights Reserved. H2O x mruby 概説 16
  17. 17. Copyright © DeNA Co.,Ltd. All Rights Reserved. H2Oのアーキテクチャ !  マルチスレッド x イベントループ !  デフォルトでコア数と同じ数のスレッドが起動 !  各スレッドがイベント駆動でリクエストを捌く !  外部I/Oによるブロックはスループットに直結するので、 全てのI/O絡みの処理をノンブロッキングで⾏うことが肝要 17
  18. 18. Copyright © DeNA Co.,Ltd. All Rights Reserved. mruby中の処理もノンブロッキングでやりたい !  何も考えずに既存のmrbgemsを使うと簡単にブロックする !  イベントループ対応された既存mrbgemsはほとんど無い !  特にh2oでは独⾃の(⾼速な!)イベントループを使っており、 例えばlibuv対応のmrbgemsがあっても普通には使えない !  CにもAnyEventみたいなレイヤがあればいいんですけどね !  H2O x mruby ではイベント駆動の恩恵を受けられないのか? 18
  19. 19. Copyright © DeNA Co.,Ltd. All Rights Reserved. それFiberでできるよ !  Fiber: Rubyにおけるコルーチン/継続/協調的マルチタスク !  Perlでいうと…なんでしょうね?Coro?(使ったことない) 19
  20. 20. Copyright © DeNA Co.,Ltd. All Rights Reserved. FiberによるノンブロッキングI/O 20
  21. 21. Copyright © DeNA Co.,Ltd. All Rights Reserved. FiberによるノンブロッキングI/O !  実際のH2Oのコード !  https://github.com/h2o/h2o/blob/master/lib/ handler/mruby/embedded/core.rb#L51 !  設定ファイルから得たmrubyハンドラの コードを、Fiber Runnerに変換 !  最適化のため、⾒た⽬がそこそこ怖い !  作成したFiberの再利⽤ !  begin-rescueのオーバーヘッド回避 !  ちなみにv2.3からはもっと怖い感じにな ります 21
  22. 22. Copyright © DeNA Co.,Ltd. All Rights Reserved. Rack ApplicaIon としての mrubyハンドラ !  Rack仕様に則ったRackアプリケーションとして(ほぼ)記述可能 !  v2.2以前はレスポンスの書き換えが不可だが、v2.3以降で出来るように なる予定 22
  23. 23. Copyright © DeNA Co.,Ltd. All Rights Reserved. Rack ApplicaIon としての mrubyハンドラ !  mrubyコードを外部ファイルに置くことも勿論可能 !  Rack Middleware的なことも勿論可能 !  そのうちRack::Builder互換のDSLも作りたい 23
  24. 24. Copyright © DeNA Co.,Ltd. All Rights Reserved. H2O x mruby で あれやこれやできるよという話 24
  25. 25. Copyright © DeNA Co.,Ltd. All Rights Reserved. Access Control 25
  26. 26. Copyright © DeNA Co.,Ltd. All Rights Reserved. Access Control !  v2.1から、aclという組み込みメソッドを⽤意 !  アクセス制御が簡単に書けるように !  サンプルケース !  127.0.0.1からのアクセスは常に許可 !  192.168.*以外からのcurlは403 !  特定のipからのリクエストには503 !  “moved” が含まれるパスへのリクエストは特定URLにリダイレクト !  /admin/ 以下へのリクエストにはBasic認証を要求 26
  27. 27. Copyright © DeNA Co.,Ltd. All Rights Reserved. Access Control - nginxの場合 !  多分こんな感じ !  つれぇ… !  Ifの条件中で、andやorが使 えないしネストもできない !  変数使ってうまいこと やりくり… !  そもそも公式がif is evilと⾔ っている模様…何だと… !  https://www.nginx.com/ resources/wiki/start/topics/ depth/ifisevil/ 27 警告: そんなにちゃんと動作確認してないので参考にしないで下さい
  28. 28. Copyright © DeNA Co.,Ltd. All Rights Reserved. Access Control - Apacheの場合 !  僕の低いApache⼒では不可能でした !  正直にいうと調べる気も起きませんでした 28
  29. 29. Copyright © DeNA Co.,Ltd. All Rights Reserved. Access Control - H2O 2.0以前の場合 !  うっこわい !  まぁやりたいことが素直にできはするし、読めもする !  しかしもうちょっとなんとかならないものか 29
  30. 30. Copyright © DeNA Co.,Ltd. All Rights Reserved. Access Control - H2O 2.1以降 !  なんとなくエレガントに書けるようになった! !  aclブロックの中では各種DSLメソッドが使える !  allow: 即座に後続のハンドラにpass through !  deny: 即座に403 !  etc.. !  各メソッドのブロック内では、適⽤条件を好きに書ける !  ここでもaddrやpathなど、envにアクセスするための DSLメソッドが使える 30
  31. 31. Copyright © DeNA Co.,Ltd. All Rights Reserved. DoS DetecIon 31
  32. 32. Copyright © DeNA Co.,Ltd. All Rights Reserved. DoS DetecIon !  標準でDoSDetectorというライブラリを提供 !  IPアドレスベースで単位時間内のリクエスト数をカウントし、 超えたら⼀定期間BANする (403 Forbidden) !  Apacheのmod_dosdetectorに相当 !  https://github.com/stanaka/mod_dosdetector !  ロジックも参考にさせて頂きました 32
  33. 33. Copyright © DeNA Co.,Ltd. All Rights Reserved. DoS DetecIon - Advanced !  DoS判定時の処理はcallbackでカスタマイズ可能 !  ログ吐いたりアラートメール⾶ばしたり !  strategyを⾃作すれば、DoS判定ロジックもカスタマイズ可能 33
  34. 34. Copyright © DeNA Co.,Ltd. All Rights Reserved. DoS DetecIon – もろもろ !  注意点 !  現在の実装は、スレッド単位のローカル変数でカウントしているの で、閾値をホスト数×スレッド数で割り算する必要がある !  v2.3あたりから、mrubyからRedisが使えるようになる予定(後 述)なので、そういったstrategyを⽤意する予定がなくはない !  Pure mrubyで書かれているため、モジュール⾃作したいユーザーさんの サンプルとして良いのでは !  なおPure mrubyコードなら単にrequireするだけでよく、 H2Oの再ビルドは不要 !  c等を使ってmrbgemsを書きたい場合は、mrubyとh2oをビルドし なおす必要あり !  個⼈的にはjoin初⽇に書いたやつなので思い⼊れがある (⾃分で使ってないけど) 34
  35. 35. Copyright © DeNA Co.,Ltd. All Rights Reserved. HTTP Request 35
  36. 36. Copyright © DeNA Co.,Ltd. All Rights Reserved. HTTP Request !  mrubyハンドラからノンブロッキングなHTTP Requestが⾶ばせる !  proxy的なことが容易にできる !  2段階の同期ポイント !  req.joinしてステータスとヘッダのみを取得 !  resp[2].joinしてボディを取得 36
  37. 37. Copyright © DeNA Co.,Ltd. All Rights Reserved. HTTP Request - 例1 !  起動時にetcdから設定値を取得するサンプル(v2.3〜) !  資料からは詳細省いたけど、このハンドラの外側で⾮同期処理させるや つ⼤変だったんですよ…詳しくはWebで… !  逆にいうと今はハンドラの外ではhttp_requestとか使えないので お気をつけ下さい 37
  38. 38. Copyright © DeNA Co.,Ltd. All Rights Reserved. HTTP Request - 例2 !  複数リクエストを同時に投げて、結合して返すサンプル 38
  39. 39. Copyright © DeNA Co.,Ltd. All Rights Reserved. HTTP Request - 例2 - もっと効率よく !  こんな⾵にすると、より早くレスポンスのパイプラインに載せられる !  メモリフットプリントも⼩さくなる(多分) 39
  40. 40. Copyright © DeNA Co.,Ltd. All Rights Reserved. HTTP Request - 例3 !  ESI (Edge Side Includes) のサンプル !  ちなみにESIとは !  エッジサーバ(e.g. CDN)側で、 動的にコンテンツを組み⽴てるためのマークアップ仕様(超古い) !  ページを構成する部品ごとにキャッシュできる 40
  41. 41. Copyright © DeNA Co.,Ltd. All Rights Reserved. HTTP Request - 例3 !  適当にこんなの作って… 41 <esi:include>タグの src属性を抜き出して HTTPリクエストを送信 bodyを受信(というか同期)
  42. 42. Copyright © DeNA Co.,Ltd. All Rights Reserved. HTTP Request - 例3 !  こう !  シンプルに⾒えるが、この機能をcで実装することをご想像下さい… 42
  43. 43. Copyright © DeNA Co.,Ltd. All Rights Reserved. Redis 43
  44. 44. Copyright © DeNA Co.,Ltd. All Rights Reserved. Redis !  v2.2から、TLS Session Resumptionのバックエンドとして使うため、 ネイティブでredisサポートしてます !  ID basedの場合:キャッシュの保管場所として !  ticket basedの場合:チケットの保管場所として !  ちなみにauto rotate機能付き !  2.1以前はmemcachedだけだった !  HiRedisをラップしてh2oコアに持ってる !  v2.3以降 !  そのredisライブラリをmrubyからも扱えるようにした H2O::Redisがリリース予定 !  キャッシュをredisから取ってきて返却する、みたいな処理を mrubyで⾏うことが可能に 44
  45. 45. Copyright © DeNA Co.,Ltd. All Rights Reserved. Redis: 例 !  静的なページのHTTPレスポンスをまるっとredisにキャッシュする例 45
  46. 46. Copyright © DeNA Co.,Ltd. All Rights Reserved. Other TCP Bindings 46
  47. 47. Copyright © DeNA Co.,Ltd. All Rights Reserved. Other TCP Bindings !  HTTPやRedisやコア側で実装がすでにあったからそれを使えばよかった !  でも今後、他のプロトコルを使いたい場合等はどうする? !  MySQL, memcached, etc.. !  個別にcでプロトコルバインディングを実装してくのはしんどい 47
  48. 48. Copyright © DeNA Co.,Ltd. All Rights Reserved. Other TCP Bindings !  ノンブロッキングなH2O::TCPSocketを作った !  個別のバインディングは、mrubyでこれを使いつつ書けばよい !  ので、⾮常に書きやすくなったはず !  mrubyのパフォーマンスが問題になることは ほとんど無いだろう想定 !  とりあえずMySQLでも書いてみる予定(予定は未定) 48
  49. 49. Copyright © DeNA Co.,Ltd. All Rights Reserved. Image Filter 49
  50. 50. Copyright © DeNA Co.,Ltd. All Rights Reserved. Image Filter !  発表駆動開発で、今⽇までになんとかそれっぽいもの作ろうと思ってた んですけど、間に合いませんでした… !  いちおう今後こんなことも考えてますよ、的なノリで紹介させて下さい !  主旨: !  mod_small_light的な、画像をオンザフライで縮⼩やクリップして くれるやつが欲しい !  流⽯にmrubyで画像処理をするのは遅いだろう !  外部コマンド実⾏できたらよいのでは !  それ以外にも出来ることの幅が広がるし 50
  51. 51. Copyright © DeNA Co.,Ltd. All Rights Reserved. ベンチマーク 51
  52. 52. Copyright © DeNA Co.,Ltd. All Rights Reserved. ベンチマーク !  ⽰したいこと !  mrubyであれこれやっても、システムのボトルネックはどうせ I/Oもしくはアプリケーションなので、問題にならないはず !  同じ処理をするnginxと⽐較して誤差レベルの劣化しかないはず !  サンプルアプリ: !  単純なTODOリストみたいなやつのJSON API !  https://github.com/i110/tinytodo !  設定ファイルやwrk scriptも⼊ってます 52
  53. 53. Copyright © DeNA Co.,Ltd. All Rights Reserved. ベンチマーク構成 53 !  検証環境 !  EC2東京リージョン c4-8xlarge 3台 (論理コア数36) !  リバースプロキシ(H2O or nginx) !  アプリケーションサーバ (Plack app) !  負荷かけサーバ(wrk with lua scripting) !  同⼀プレイスメントグループ、拡張ネットワーキング有効 負荷かけ サーバ revproxy (H2O or nginx) クソアプリ 負荷 proxy sqlite
  54. 54. Copyright © DeNA Co.,Ltd. All Rights Reserved. 事前ベンチマーク 54 !  ベンチ取る前にまず、H2O x mrubyとnginxの純粋な性能差を調べよう !  アプリ抜きで、それぞれが直接200返してみる !  mrubyぶんのoverheadのせいでnginxのほうが速い想定 負荷かけ サーバ revproxy (H2O or nginx) クソアプリ 負荷 sqlite 問答無⽤で 200
  55. 55. Copyright © DeNA Co.,Ltd. All Rights Reserved. 事前ベンチマーク – 結果 55 !  この時点でH2Oのほうが速いんですけど…まじで… !  クソアプリいらなかったわ… Requests per second
  56. 56. Copyright © DeNA Co.,Ltd. All Rights Reserved. ベンチマーク: 考察 !  よくわからない !  まぁnginxもごにょごにょ書きすぎると遅くなるということですかね !  とにかく⼤勝利でよかった !  少なくともほとんどのユースケースでは、mrubyであれこれやっても 問題ないと⾔えるのではないか 56
  57. 57. Copyright © DeNA Co.,Ltd. All Rights Reserved. 結論 57
  58. 58. Copyright © DeNA Co.,Ltd. All Rights Reserved. 結論 !  H2O x mrubyでみんなで幸せになろう !  つらみのある設定ファイルとはさよならしよう !  ⾃由にサーバを拡張していこう !  簡単に拡張機能を書けるので是⾮書いてみてください !  ブログに書いたりgithubで公開してくれる等すると⼤変嬉しいです !  Feature requestしてくれるだけでも⼤変嬉しいです !  ⾊々な機能&改善が⼊る予定のv2.3にご期待下さい !  むしろコアまわりのPRもお待ちしております 58

×