Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ngx_mrubyとfiberの話 (未完成版)
Search
Ryo Okubo
January 24, 2018
Programming
2
320
ngx_mrubyとfiberの話 (未完成版)
ngx_mruby のかんたんな紹介と、 fiber を組み込んで色々やりたかったけど挫折してる話
Ryo Okubo
January 24, 2018
Tweet
Share
More Decks by Ryo Okubo
See All by Ryo Okubo
UbieのAIパートナーを支えるコンテキストエンジニアリング実践
syucream
2
1k
メルカリ・メルペイの成長を支える データ基盤とはどんなものか
syucream
7
7.1k
バッチとストリーミング、それぞれの障害に立ち向かう
syucream
3
3.7k
How Scala works at Mercari
syucream
2
1.1k
Production-ready stream data pipeline in Merpay, Inc
syucream
2
13k
データとML周辺エンジニアリン グを考える会 #2 イントロ
syucream
0
640
マイクロサービスにおける ログ収集の課題と取り組み
syucream
7
2.7k
Stream Data Pipeline for Microservices in Merpay
syucream
6
1.2k
メルペイにおける、マイクロサービスに寄り添うログ収集基盤 / Microservices-frendly Data Pipeline
syucream
0
18k
Other Decks in Programming
See All in Programming
CSC305 Lecture 05
javiergs
PRO
0
210
Cloudflare AgentsとAI SDKでAIエージェントを作ってみた
briete
0
130
XP, Testing and ninja testing ZOZ5
m_seki
3
390
NetworkXとGNNで学ぶグラフデータ分析入門〜複雑な関係性を解き明かすPythonの力〜
mhrtech
3
1.1k
2分台で1500examples完走!爆速CIを支える環境構築術 - Kaigi on Rails 2025
falcon8823
3
3.4k
私はどうやって技術力を上げたのか
yusukebe
43
18k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
200
なぜGoのジェネリクスはこの形なのか? Featherweight Goが明かす設計の核心
ryotaros
7
1k
Breaking Up with Big ViewModels — Without Breaking Your Architecture (droidcon Berlin 2025)
steliosf
PRO
1
350
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
2
480
ポスターセッション: 「まっすぐ行って、右!」って言ってラズパイカーを動かしたい 〜生成AI × Raspberry Pi Pico × Gradioの試作メモ〜
komofr
0
1.1k
Reduxモダナイズ 〜コードのモダン化を通して、将来のライブラリ移行に備える〜
pvcresin
2
690
Featured
See All Featured
Agile that works and the tools we love
rasmusluckow
331
21k
We Have a Design System, Now What?
morganepeng
53
7.8k
Making the Leap to Tech Lead
cromwellryan
135
9.5k
Building a Modern Day E-commerce SEO Strategy
aleyda
43
7.7k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
The Cult of Friendly URLs
andyhume
79
6.6k
Fireside Chat
paigeccino
40
3.7k
The Art of Programming - Codeland 2020
erikaheidi
56
14k
Into the Great Unknown - MozCon
thekraken
40
2.1k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Build your cross-platform service in a week with App Engine
jlugia
232
18k
Transcript
ngx_mrubyとfiberの話 (未完成版) @syu_cream
whoami • @syu_cream • 仕事で Go, Scala, mrubyは趣味 • mruby
の実装に関する同人誌書いた ◦ https://www.amazon.co.jp/dp/B06XZ9LXSB • 作った mruby 関連プロダクト ◦ mruby-rspec ◦ mruby-serverspec ◦ mruby-k2hash ◦ mruby-rocksdb ◦ ts_mruby(mruby extension for Apache TrafficServer)
今日の話 • この会のテーマを見ると... • ngx_mruby, fiber 周りで試行錯誤した話需要あるかも? • と思ったのでそんな感じの話します
ngx_mruby • 設定や簡単なロジックを mruby で拡張可能にする nginx モ ジュール ◦ https://github.com/matsumotory/ngx_mruby
• ngx_mruby 利用例: ◦ ランダムに upstream を切り替える ◦ 特定 IP アドレス以外からのアクセスを遮断する
ngx_mruby 利用の具体例 • User-Agent が空なリクエストに400を返す ◦ 以下はnginx.confにインラインで書いてるけど別ファイルに分離可能
ngx_mruby における非同期処理 • 依存 mrbgems で容易に I/O でブロックする ◦ ノンブロッキング
I/O のサポートはしていない ◦ なので性能面でつらい場面が出る可能性がある • h2oでも試行錯誤してた ◦ https://www.slideshare.net/ichitonagata/h2o-x-mruby-72949986 • ngx_lua はノンブロッキング処理を頑張っている ◦ ngx.sleep, ngx.location.capture ◦ ngx.socket.tcp, ngx.socket.udp ◦ さらに気になる人は “nginx実践入門” もチェック!
ngx_mrubyでもノンブロッキングI/Oしたい! • nginx を使う以上イベント駆動の恩恵を受けたい • lua ならコルーチンで処理の継続ができる • mruby の場合...
継続可能な処理は fiber で表現可能 • まずノンブロッキング sleep を実装してみる ◦ 実用性で言うと subrequest が欲しいが難易度が高い ◦ 第一歩は簡単で分かりやすい目標にする
ngx_mruby fiber • ngx_mruby で fiber サポートを試みた ◦ まずは mruby
の実行コードを fiber に包んで VM に実行させる ◦ その後 fiber の具体利用例として sleep を実装する ▪ Nginx::Async.sleep という名前付けた
事前調査・学習の流れ • mruby の ソースコードをざっくり読む ◦ include/ 以下のヘッダと必要なら src/, mrbgems/mruby-fiber/
• ngx_mruby のソースコードを読む ◦ 特に src/http/ngx_http_mruby_module.c ◦ VM の実行部分を触ることになるので mrb_run() 周りを • echo-nginx-module のソースコードを読む ◦ ノンブロッキング sleep を実装している module ▪ えっ、 echo module って何だよ(哲学) ▪ src/ngx_http_echo_sleep.c が参考になった • nginx のソースコードをざっくり読む ◦ 上記で解決しなかった場合はサボらない
実装 • forkした以下のリポジトリにあります ◦ https://github.com/syucream/ngx_mruby • やったこと ◦ mrb_run() で実行する
RProc 構造体の値を fiber でラップ ◦ fiber を yield されるまで実行 ◦ Nginx::Async.sleepのC関数内で yield して nginx の timer をセット ▪ ngx_add_timer() にハンドラと秒数を渡す ◦ ハンドラ内で fiber を resume & nginx のイベントを進める ▪ ngx_http_core_run_phase() 経由で操作
Nginx::Async.sleep の動作 • コード例 ◦ 上がブロックする版、下がしない版 • 実際の動作 ◦ デモします
ngx_mruby によるノンブロッキング処理の展望 • sleep だけでは用途は限定される • subrequest が扱えるとやれることが多くなる ◦ ACL
設定を他 HTTP サーバに分離してそれを参照など • ngx_lua の ngx.socket.tcp など欲しいが、険しい道 ◦ mruby-redis とか使いたいライブラリに手を入れるの? ◦ 片っ端から ngx_mruby 用の修正入れるのは高コスト • Thread Pool と連携してなにかできないかな? ◦ https://www.nginx.com/blog/thread-pools-boost-performance-9x/ ◦ ブロックする処理の実装は無理して変更しない ◦ Thread Pool に投げるようにして、終わったら resume する
実装でハマった(ハマってる)箇所1 • mruby の fiber 操作の C 関数がつらい ◦ yield/resume
関数の 2 つしかない ◦ new する C 関数が無いので funcall 経由でオブジェクト生成 ▪ proc オブジェクトと fiber class の mrb_value を用意 ▪ mrb_funcall_with_block() に渡してオブジェクトを得る ◦ その後 mrb_fiber_resume() するも... • 本スライドでは Fiber を Proc オブジェクトでラップして Proc#call 経由で操作するメソッドを Ruby で実装☺
実装でハマった(ハマってる)箇所2 • 生成された mruby のコードの OP_STOP 命令問題 ◦ yield した後もちろん別の
mruby コードが実行される可能性ある ◦ そしてそのコードは末尾に OP_STOP を持つ ▪ mrb_generate_code() で生成されたコードは持つはず ◦ OP_STOP で VM が停止し、 fiber が resume できない事態に! ◦ 一旦 OP_STOP を OP_RETURN に置換するという荒業で対応 ▪ 過去に h2o がこの対策取ってたらしい ▪ 本来どうするべきなんだろうか ...
実装でハマった(ハマってる)箇所3 • 特定ハンドラでしか動作確認できていない ◦ 現状、 rewrite, access handler でしか動作しない ◦
content handlerとかで動かしたら死ぬ • nginx の理解がそもそも足りていない気がする
おわりに • ngx_mrubyの試行錯誤コード読み書き話ウケるかも! • と思ったのでそんな感じの話します • と意気込んだものの絶賛WIPです • それでも何かの参考になれば幸いです