Advertisement

More Related Content

Slideshows for you(20)

Similar to mruby_nginx_module at pyfes 2013.11(20)

Advertisement

mruby_nginx_module at pyfes 2013.11

  1. mruby_nginx_module ∼ 久保 達彦 cubicdaiya@gmail.com pyfes 2013/11/30
  2. 自己紹介 ✦ 久保 達彦(H.N:bokko) ✦ @cubicdaiya(twitter, github) ✦ Senior Software Engineer@pixiv Inc. ✦ インフラチーム所属 ✦ ミドルウェアの開発・運用とかやってます
  3. Goはじめました
  4. 普段はnginxのモジュールとか作ってます ✦ mruby_nginx_module ✦ ✦ ngx_small_light ✦ ✦ Dynamic Image Transformation for nginx ngx_access_token ✦ ✦ Embed mruby into nginx Porting of mod_access_token into nginx Nginx本体にも2件ほどパッチ送りました
  5. WEB+DBでもnginxの記事を書きました WEB+DB PRESS Vol.72 ! □詳解nginx ! 設定の柔軟性と 優れたスケーラビリティ ! □共著者 @harukasan @semind
  6. nginx in pixiv ✦ リバースプロキシとかキャッシュとかWebDAVとか 色々な箇所で稼働しています ✦ Using ngx_lua in pixiv ✦ http://www.slideshare.net/harukayon/ngx-lua-public ✦ @harukasan++
  7. とあるpixivを支えるインフラエンジニア談
  8. mruby_nginx_module ∼Embed mruby into nginx∼
  9. mruby_nginx_module ✦ nginxの拡張モジュール ✦ nginx.confでmrubyが書ける ✦ nginxのモジュールがmrubyで書ける ✦ ngx_mrubyからfork at 2013/07 ✦ ✦ それまではPull Request送る形で開発に参加してました http://git.io/d3sJtw
  10. ngx_mrubyとの違い ✦ (mod|ngx)_mrubyはWebサーバの拡張記述統一が目的の一つ ✦ ✦ ✦ Apacheでもnginxでもできる限り同じように書けるのが重要 機能は極力mrbgemsで実現する方向 mruby_nginx_moduleはnginxとの親和性を重視 ✦ 機能は極力nginxのAPIで実現する方向
  11. ドキュメント http://cubicdaiya.github.io/ mruby_nginx_module/
  12. mruby ✦ 軽量Ruby ✦ 組み込み分野向けにまつもとゆきひろ氏が開発 ✦ Cと連携しやすいように設計されてる ✦ 個人的にはリッチなLuaというイメージ
  13. Luaから見たmruby ✦ Cとの連携が非常に楽 ✦ ✦ Luaのスタック操作に比べるとかなり直感的 オブジェクト指向機能のサポート ✦ Luaでもtableで頑張ることはできるがmrubyに 比べると弱い
  14. ngx_luaとmruby_nginx_module (あるいはngx_mruby)
  15. ngx_lua ✦ ノンブロッキングアーキテクチャ ✦ nginxやその他拡張モジュールとの親和性が非常に高い ✦ 関連モジュールが豊富(lua-resty-xxx) ✦ 拡張モジュールというかもはやフレームワークの域 ✦ lua-jitと組み合わせたら鬼に金棒 ✦ OpenRestyの中核モジュール
  16. mruby_nginx_module ✦ まだまだ発展途上 ✦ 機能とかライブラリとかいろいろ足りてない ✦ ノンブロッキングなアーキテクチャにするのが当面の課題 ✦ フック関連のディレクティブ群はほぼ同等レベルまで実装済 ✦ mruby_(rewrite|access|content|log)_handler等
  17. 今のところ使える機能 ✦ コードキャッシュ ✦ 各種ハンドラへのフック(rewrite,access,content,log) ✦ ヘッダおよびボディのフィルタリング ✦ nginxの変数へのアクセス(set & get) ✦ Nginx::(Request|Context|Time|Base64|Digest|etc) ✦ ✦ by Nginx Core API(not mrbgems) Regexp(PCREベース)
  18. nginxの実行フェーズとディレクティブ一覧 nginxの処理フェーズ(実行順) mruby_nginx_moduleのディレクティブ start-up nginx & modules mruby_init, server rewrite find config rewrite post rewrite pre-access access post-access try files content log 備考 mruby_require serverコンテキストのrewrite 該当するlocationの探索 mruby_rewrite_handler locationのrewrite ! mruby_access_handler ファイルへのアクセス ! try_files mruby_content_handler mruby_log_handler bodyの生成 ロギング
  19. その他のディレクティブ mruby_nginx_moduleのディレクティブ mruby_cache mruby_set 用途 コードキャッシュのOn/Off(default:On) mrubyの実行結果をnginxの変数にsetする mruby_header_filter HTTPヘッダの内容をフィルタリング or 上書きする mruby_body_filter HTTPボディの内容をフィルタリング or 上書きする
  20. Hello, World!
  21. nginxの変数にset #=> 55
  22. ファイル指定も可能 ・先頭に「/」がある場合は絶対パス ・それ以外の場合は相対パス(conf_prefixがroot)
  23. ヘッダ書き換え # 本来はtext/html
  24. レスポンスボディも(ry
  25. 各処理フェーズでデータ共有
  26. Builtin-Regexp based PCRE
  27. nginxとmrubyとPCRE ✦ nginxは正規表現処理にPCREを利用している ✦ mrubyには今のところRegexpが標準で入っていない ✦ ✦ PCREベースのmrbgemはnginxに組み込むのが困難 ✦ ✦ 別途mrbgemが必要(例:iij/mruby-regexp-pcre) nginxがpcre_(malloc|free)を上書きしてる でもPCREは使いたい
  28. なので、 ✦ iij/mruby-regexp-pcreのコードを直接取り込み & 改変 ✦ pcre_(malloc|free)をさらに上書き ✦ ✦ ngx_luaも似たようなことをやってる http://bokko.hatenablog.com/entry/2013/10/13/142154
  29. Nginx::Request ■処理中のリクエスト情報にアクセス location = /mruby { mruby_content_handler_code ' r = Nginx::Request.new Nginx.rputs(r.uri + "n") # => /mruby Nginx.rputs(r.method + "n") # => GET, POST, etc Nginx.rputs(r.protocol + "n") # => HTTP/1.x '; }
  30. Nginx::Request ■nginxの変数にアクセス location /mruby { set $maintainer "bokko"; mruby_content_handler_code ' r = Nginx::Request.new maintainer = r.var.maintainer Nginx.rputs(maintainer + "n") # => bokko '; }
  31. Nginx::Headers_in ■リクエストヘッダへのアクセス hin = Nginx::Headers_in.new host = hin["Host"] # Host header agent = hin["User-Agent"] # User-Agent header table = hin.headers_in_hash # all headers with hash table
  32. Nginx::Headers_out ■レスポンスヘッダへのアクセス time = Nginx::Time.time() http_time = Nginx::Time.http_time(time + 60 * 60 * 24) ! # Expiresヘッダを設定 hout = Nginx::Headers_out.new hout["Expires"] = http_time.to_s
  33. Nginx::Time ■nginxのtime系APIのラッパー time = Nginx::Time.time # => epoch value ! time = 1377710189 Nginx::Time.http_time(time) # => Wed, 28 Aug 2013 17:16:29 GMT Nginx::Time.cookie_time(time) # => Wed, 28-Aug-13 17:16:29 GMT ! Nginx::Time.utc_time Nginx::Time.local_time # => UTC Time(2013-11-30 xx:xx:xx) # => local time(2013-11-30 xx:xx:xx) ! http_time = Nginx::Time.http_time(time) Nginx::Time.parse_http_time(http_time) # => 1377710189
  34. Nginx::Digest ■MD5, SHA1, HMAC-SHA1, etc md5 = Nginx::Digest.md5("bokko") Nginx::Digest.hexdigest(md5) # => fe9749… ! sha1 = Nginx::Digest.sha1("bokko") Nginx::Digest.hexdigest(sha1) # => cea3d1… ! hmac_sha1 = Nginx::Digest.hmac_sha1("data", "key") Nginx::Digest.hexdigest(hmac_sha1) # => 10415…
  35. Nginx::Base64 ■Base64 encode/decode encoded = Nginx::Base64.encode("bokko") # => Ym9ra28= Nginx::Base64.decode(encoded) # => bokko
  36. 少し発展的な例
  37. (mod|ngx)_access_token っぽいアクセス認証
  38. (mod|ngx)_access_token ✦ S3のクエリ文字列認証っぽい機能を提供 ✦ ✦ ✦ 特定のアクセストークンに基づいた認証 リソースの有効期限設定 mod_access_token ✦ ✦ livedoor(現LINE)が開発 ngx_access_token ✦ @cubicdaiyaが開発
  39. xxx_access_tokenの認証方式 以下のパラメータをリクエストURLに付加する ! ・AccessKey -> 公開 ・Expires 文字列 -> 有効期限(エポック値) ・Signature -> シグネチャ ! Text = Method + Uri + Expires + AccessKey Signature = Base64(HMAC_SHA1(Text, (※) SecretKey)) ! (※)秘密 文字列(サーバ側で設定)
  40. ngx_access_token by mruby_nginx_module
  41. (mod|ngx)_access_tokenと比べて、 ✦ mod_access_token by C ✦ ✦ ngx_access_token by C ✦ ✦ 約200行 約300行 ngx_access_token by mruby ✦ 約10行 スクリプト言語の力ってすごいですね
  42. 今後の課題 ✦ 共有メモリAPI(Nginx::Shared) ✦ サブリクエストAPI(Nginx::SubRequest) ✦ ノンブロッキングソケットAPI(Nginx::Socket) ✦ Fiber(コルーチン)導入 ✦ etc
Advertisement