Top Banner
Copyright © DeNA Co.,Ltd. All Rights Reserved. H2O x mruby ⼈はどれだけ 幸せになれるのか March 4, 2017 @i110 Technology Development, System Management Unit DeNA Co., Ltd. YAPC::Kansai 御中
58

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

Mar 19, 2017

Download

Engineering

Ichito Nagata
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: H2O x mrubyで人はどれだけ幸せになれるのか

Copyright©DeNACo.,Ltd.AllRightsReserved.

H2Oxmrubyで⼈はどれだけ幸せになれるのか

March4,2017

@i110TechnologyDevelopment,SystemManagementUnitDeNACo.,Ltd.

YAPC::Kansai御中

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

⾃⼰紹介

!  @i110

!  株式会社ディー・エヌ・エー!  システム本部技術開発室所属

⁃  ⾊んな⼈が⾊んなことをやってる部署⁃  平均年齢⾼め

!  昨年夏くらいにあれやこれやあってH2Oの開発にjoin

!  現在、業務時間の全てをH2Oの開発に注いでいる状態⁃  最近はmrubyまわりの機能追加&改善が多め

2

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

H2Oについてさらっと

3

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

H2Oとは

!  https://h2o.examp1e.net/!  Google翻訳いわく

!  おおむねこの通りです(⾚字部分を除いて)

!  みんな⼤好き某kazuhosanが開発!  現在の最新verはv2.2.0-beta1

4

H2Oは、古い世代のWebサーバーと⽐較して、CPU使⽤率が低いユーザーに迅速な応答を提供する、

新しい世代のHTTPサーバーです。基盤から設計されたサーバーは、優先コンテンツ配信とサーバープッシュを含むHTTP/2機能をフルに活⽤し、

Webサイトの訪問者に有望な経験を提供します。

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

H2Oはなぜ⾼速なのか

!  主に3つの理由による1.  優先度制御が優秀2.  先進仕様への対応の速さ(Cache-digests、TLS1.3、etc..)3.  neatかつ無駄のない実装

!  詳しくはWebで!

5

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

しかし…

!  Apacheとnginxつよい

!  理由(私⾒)1.  豊富なモジュール群2.  情報の多さ3.  枯れてる度

!  私は当然H2Oが最⾼のWebサーバーだと信じているので世界の⼈々をより幸せにするためにH2Oが普及してほしい

!  速いことはわかった。それ以外に何が必要か

6

hGps://w3techs.com/technologies/overview/web_server/all

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

便利で快適なWebサーバーへ

!  Apacheやnginxに出来て、H2Oに出来ないことを無くしたい!  拡張モジュールの整備!  ユーザー⾃⾝による拡張モジュールの書きやすさ

!  Apacheやnginxよりも、同じことが簡単にできるようにしたい!  設定ファイルの柔軟さ&テスタビリティ

!  あとドキュメントももっと沢⼭書きますすいません

7

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

組み込み⾔語としてのmrubyの採⽤

!  2015年7⽉にリリースしたv1.4で、RyosukeMatsumoto(@matsumotory)さんが初期実装

!  リクエストハンドラとしてmrubyのコードを実⾏できる

8

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

組み込み⾔語としてのmrubyの採⽤

!  ApacheやNginxよりも強いサポート!  コアに付属、デフォルトでON!  ⾮同期I/Oを可能にする各種ライブラリの提供!  RackSpecに準拠した⾃然なインターフェース!  今後さらに⼿厚くしていく予定

!  想定⽤途!  アクセス制御、URIリライト、レスポンスの書き換え、etc..!  プログラマブルで柔軟な設定が可能に!  サーバー機能の⼿軽な拡張も可能に

9

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

mrubyの何がどう嬉しいのか

1.  サーバ機能の拡張性2.  設定の柔軟性&テスタビリティ

10

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

1.サーバ機能の拡張性

!  ユーザ⾃⾝が、欲しい機能をさくっと書いて追加できる状態が理想!  しかしcでモジュール作るのは⼤変

!  Cloudbleed(2017)!  https://blog.cloudflare.com/incident-report-on-memory-leak-caused-by-cloudflare-

parser-bug/

!  Cloudflare(CDN)で発⽣したユーザ秘匿情報の漏えい問題!  原因は、内製のnginxモジュール(HTMLパーサ)のバグ

!  ポインタ管理のミスによるバッファオーバーラン!  mrubyで書けば原理的に発⽣しえない問題

!  コードにバグがあっても、バッファオーバーランが発⽣することはない

11

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

2.設定の柔軟性&テスタビリティ

!  個⼈的な話にはなりますが、Apacheやnginxのディレクティブを⼀切覚えられない(覚えるつもりもない)ので毎回サーバー⽴てるたびに2時間くらいぐぐっている

!  凶悪なmod_rewrite、ミスりやすいアクセス制御、何故か効かないsection…

!  理想!  シンプルなことはディレクティブで簡単に!  複雑なことはプログラマブルにがっつり

12

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

なんとなく印象と⼀致する参考値

!  ⽐較!  Excelnotworking:1,170万件!  PowerPointnotworking:1,040万件!  nginxconfignotworking:73万件

!  nginxはユーザーの⾃⼰解決能⼒が⾼いというのもありそう

13

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

2.設定の柔軟性&テスタビリティ

!  ディレクティブによる設定だと、設定がちゃんと効いているか実際にリクエストを送って試してみるしかない!  設定追加したらConflictして別の箇所が動かなくなった!とか…

!  複雑であるからこそテストを書きたいのに…

!  mrubyならテストを書ける!  粒度の細かい単体テスト!  スタブを使ったテスト!  etc..

!  近⽇中に何かしらのHowToを公開します(たぶん)

14

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

というわけで、本⽇は

!  H2Oxmrubyの仕組みの簡単な解説!  知られざる機能の紹介

!  ステルスで追加した機能!  近々マージ予定の機能

15

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

H2Oxmruby概説

16

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

H2Oのアーキテクチャ

!  マルチスレッドxイベントループ!  デフォルトでコア数と同じ数のスレッドが起動!  各スレッドがイベント駆動でリクエストを捌く

!  外部I/Oによるブロックはスループットに直結するので、全てのI/O絡みの処理をノンブロッキングで⾏うことが肝要

17

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

mruby中の処理もノンブロッキングでやりたい

!  何も考えずに既存のmrbgemsを使うと簡単にブロックする

!  イベントループ対応された既存mrbgemsはほとんど無い!  特にh2oでは独⾃の(⾼速な!)イベントループを使っており、例えばlibuv対応のmrbgemsがあっても普通には使えない

!  CにもAnyEventみたいなレイヤがあればいいんですけどね

!  H2Oxmrubyではイベント駆動の恩恵を受けられないのか?

18

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

それFiberでできるよ

!  Fiber:Rubyにおけるコルーチン/継続/協調的マルチタスク

!  Perlでいうと…なんでしょうね?Coro?(使ったことない)

19

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

FiberによるノンブロッキングI/O

20

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

FiberによるノンブロッキングI/O

!  実際のH2Oのコード!  https://github.com/h2o/h2o/blob/master/lib/

handler/mruby/embedded/core.rb#L51

!  設定ファイルから得たmrubyハンドラのコードを、FiberRunnerに変換

!  最適化のため、⾒た⽬がそこそこ怖い!  作成したFiberの再利⽤!  begin-rescueのオーバーヘッド回避

!  ちなみにv2.3からはもっと怖い感じになります

21

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

RackApplicaIonとしてのmrubyハンドラ

!  Rack仕様に則ったRackアプリケーションとして(ほぼ)記述可能!  v2.2以前はレスポンスの書き換えが不可だが、v2.3以降で出来るようになる予定

22

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

RackApplicaIonとしてのmrubyハンドラ

!  mrubyコードを外部ファイルに置くことも勿論可能

!  RackMiddleware的なことも勿論可能

!  そのうちRack::Builder互換のDSLも作りたい

23

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

H2Oxmrubyであれやこれやできるよという話

24

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

AccessControl

25

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

AccessControl

!  v2.1から、aclという組み込みメソッドを⽤意!  アクセス制御が簡単に書けるように

!  サンプルケース!  127.0.0.1からのアクセスは常に許可!  192.168.*以外からのcurlは403!  特定のipからのリクエストには503!  “moved”が含まれるパスへのリクエストは特定URLにリダイレクト!  /admin/以下へのリクエストにはBasic認証を要求

26

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

AccessControl-nginxの場合

!  多分こんな感じ

!  つれぇ…!  Ifの条件中で、andやorが使えないしネストもできない

!  変数使ってうまいことやりくり…

!  そもそも公式がifisevilと⾔っている模様…何だと…!  https://www.nginx.com/

resources/wiki/start/topics/depth/ifisevil/

27警告:そんなにちゃんと動作確認してないので参考にしないで下さい

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

AccessControl-Apacheの場合

!  僕の低いApache⼒では不可能でした!  正直にいうと調べる気も起きませんでした

28

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

AccessControl-H2O2.0以前の場合

!  うっこわい!  まぁやりたいことが素直にできはするし、読めもする!  しかしもうちょっとなんとかならないものか

29

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

AccessControl-H2O2.1以降

!  なんとなくエレガントに書けるようになった!!  aclブロックの中では各種DSLメソッドが使える

!  allow:即座に後続のハンドラにpassthrough!  deny:即座に403!  etc..

!  各メソッドのブロック内では、適⽤条件を好きに書ける!  ここでもaddrやpathなど、envにアクセスするためのDSLメソッドが使える

30

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

DoSDetecIon

31

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

DoSDetecIon

!  標準でDoSDetectorというライブラリを提供

!  IPアドレスベースで単位時間内のリクエスト数をカウントし、超えたら⼀定期間BANする(403Forbidden)

!  Apacheのmod_dosdetectorに相当!  https://github.com/stanaka/mod_dosdetector!  ロジックも参考にさせて頂きました

32

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

DoSDetecIon-Advanced

!  DoS判定時の処理はcallbackでカスタマイズ可能!  ログ吐いたりアラートメール⾶ばしたり

!  strategyを⾃作すれば、DoS判定ロジックもカスタマイズ可能

33

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

DoSDetecIon–もろもろ

!  注意点!  現在の実装は、スレッド単位のローカル変数でカウントしているので、閾値をホスト数×スレッド数で割り算する必要がある

!  v2.3あたりから、mrubyからRedisが使えるようになる予定(後述)なので、そういったstrategyを⽤意する予定がなくはない

!  Puremrubyで書かれているため、モジュール⾃作したいユーザーさんのサンプルとして良いのでは!  なおPuremrubyコードなら単にrequireするだけでよく、H2Oの再ビルドは不要

!  c等を使ってmrbgemsを書きたい場合は、mrubyとh2oをビルドしなおす必要あり

!  個⼈的にはjoin初⽇に書いたやつなので思い⼊れがある(⾃分で使ってないけど)

34

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

HTTPRequest

35

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

HTTPRequest

!  mrubyハンドラからノンブロッキングなHTTPRequestが⾶ばせる!  proxy的なことが容易にできる!  2段階の同期ポイント

!  req.joinしてステータスとヘッダのみを取得!  resp[2].joinしてボディを取得

36

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

HTTPRequest-例1

!  起動時にetcdから設定値を取得するサンプル(v2.3〜)

!  資料からは詳細省いたけど、このハンドラの外側で⾮同期処理させるやつ⼤変だったんですよ…詳しくはWebで…!  逆にいうと今はハンドラの外ではhttp_requestとか使えないのでお気をつけ下さい

37

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

HTTPRequest-例2

!  複数リクエストを同時に投げて、結合して返すサンプル

38

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

HTTPRequest-例2-もっと効率よく

!  こんな⾵にすると、より早くレスポンスのパイプラインに載せられる!  メモリフットプリントも⼩さくなる(多分)

39

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

HTTPRequest-例3

!  ESI(EdgeSideIncludes)のサンプル!  ちなみにESIとは

!  エッジサーバ(e.g.CDN)側で、動的にコンテンツを組み⽴てるためのマークアップ仕様(超古い)

!  ページを構成する部品ごとにキャッシュできる

40

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

HTTPRequest-例3

!  適当にこんなの作って…

41

<esi:include>タグのsrc属性を抜き出して

HTTPリクエストを送信

bodyを受信(というか同期)

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

HTTPRequest-例3

!  こう

!  シンプルに⾒えるが、この機能をcで実装することをご想像下さい…

42

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

Redis

43

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

Redis

!  v2.2から、TLSSessionResumptionのバックエンドとして使うため、ネイティブでredisサポートしてます!  IDbasedの場合:キャッシュの保管場所として!  ticketbasedの場合:チケットの保管場所として

!  ちなみにautorotate機能付き!  2.1以前はmemcachedだけだった

!  HiRedisをラップしてh2oコアに持ってる

!  v2.3以降!  そのredisライブラリをmrubyからも扱えるようにしたH2O::Redisがリリース予定

!  キャッシュをredisから取ってきて返却する、みたいな処理をmrubyで⾏うことが可能に

44

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

Redis:例

!  静的なページのHTTPレスポンスをまるっとredisにキャッシュする例

45

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

OtherTCPBindings

46

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

OtherTCPBindings

!  HTTPやRedisやコア側で実装がすでにあったからそれを使えばよかった

!  でも今後、他のプロトコルを使いたい場合等はどうする?!  MySQL,memcached,etc..

!  個別にcでプロトコルバインディングを実装してくのはしんどい

47

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

OtherTCPBindings

!  ノンブロッキングなH2O::TCPSocketを作った

!  個別のバインディングは、mrubyでこれを使いつつ書けばよい!  ので、⾮常に書きやすくなったはず!  mrubyのパフォーマンスが問題になることはほとんど無いだろう想定

!  とりあえずMySQLでも書いてみる予定(予定は未定)48

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

ImageFilter

49

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

ImageFilter

!  発表駆動開発で、今⽇までになんとかそれっぽいもの作ろうと思ってたんですけど、間に合いませんでした…

!  いちおう今後こんなことも考えてますよ、的なノリで紹介させて下さい

!  主旨:!  mod_small_light的な、画像をオンザフライで縮⼩やクリップしてくれるやつが欲しい

!  流⽯にmrubyで画像処理をするのは遅いだろう!  外部コマンド実⾏できたらよいのでは!  それ以外にも出来ることの幅が広がるし

50

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

ベンチマーク

51

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

ベンチマーク

!  ⽰したいこと!  mrubyであれこれやっても、システムのボトルネックはどうせI/Oもしくはアプリケーションなので、問題にならないはず

!  同じ処理をするnginxと⽐較して誤差レベルの劣化しかないはず

!  サンプルアプリ:!  単純なTODOリストみたいなやつのJSONAPI!  https://github.com/i110/tinytodo

!  設定ファイルやwrkscriptも⼊ってます

52

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

ベンチマーク構成

53

!  検証環境!  EC2東京リージョンc4-8xlarge3台(論理コア数36)

!  リバースプロキシ(H2Oornginx)!  アプリケーションサーバ(Plackapp)!  負荷かけサーバ(wrkwithluascripting)

!  同⼀プレイスメントグループ、拡張ネットワーキング有効

負荷かけサーバ

revproxy(H2Oornginx)

クソアプリ負荷 proxy

sqlite

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

事前ベンチマーク

54

!  ベンチ取る前にまず、H2Oxmrubyとnginxの純粋な性能差を調べよう!  アプリ抜きで、それぞれが直接200返してみる!  mrubyぶんのoverheadのせいでnginxのほうが速い想定

負荷かけサーバ

revproxy(H2Oornginx)

クソアプリ負荷

sqlite問答無⽤で200

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

事前ベンチマーク–結果

55

!  この時点でH2Oのほうが速いんですけど…まじで…!  クソアプリいらなかったわ…

Requ

estspersecon

d

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

ベンチマーク:考察

!  よくわからない!  まぁnginxもごにょごにょ書きすぎると遅くなるということですかね!  とにかく⼤勝利でよかった

!  少なくともほとんどのユースケースでは、mrubyであれこれやっても問題ないと⾔えるのではないか

56

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

結論

57

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

Copyright©DeNACo.,Ltd.AllRightsReserved.

結論

!  H2Oxmrubyでみんなで幸せになろう!  つらみのある設定ファイルとはさよならしよう!  ⾃由にサーバを拡張していこう

!  簡単に拡張機能を書けるので是⾮書いてみてください!  ブログに書いたりgithubで公開してくれる等すると⼤変嬉しいです!  Featurerequestしてくれるだけでも⼤変嬉しいです

!  ⾊々な機能&改善が⼊る予定のv2.3にご期待下さい!  むしろコアまわりのPRもお待ちしております

58