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 v2における ノンブロッキングなmruby実行の実装詳細
Search
Kazuhiko Yamashita
November 05, 2018
Programming
1
690
ngx_mruby v2における ノンブロッキングなmruby実行の実装詳細
RubyWouldConference2018にてngx_mruby v2のノンブロッキングインターフェースについてトークしました。
Kazuhiko Yamashita
November 05, 2018
Tweet
Share
More Decks by Kazuhiko Yamashita
See All by Kazuhiko Yamashita
新しい職場の CI が 20 分かかっていたらあなたならどうする?
pyama86
1
1.2k
事業を差別化する技術を生み出す技術
pyama86
4
1.7k
Re:Define 可用性を支える モニタリング、パフォーマンス最適化、そしてセキュリティ
pyama86
9
8.2k
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.7k
Tuning GraphQL on Rails
pyama86
2
2k
ttlcacheのここがスゴい
pyama86
1
160
クラウドサービスの 利用コストを削減する技術 - 円安の真南風を感じて -
pyama86
3
620
実践ARMアーキテクチャ移行
pyama86
2
2.5k
リモートワーク時代の守護神 PHP開発者のためのセキュリティ強化術
pyama86
3
1.3k
Other Decks in Programming
See All in Programming
0626 Findy Product Manager LT Night_高田スライド_speaker deck用
mana_takada
0
100
童醫院敏捷轉型的實踐經驗
cclai999
0
190
Haskell でアルゴリズムを抽象化する / 関数型言語で競技プログラミング
naoya
17
4.9k
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
170
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
360
来たるべき 8.0 に備えて React 19 新機能と React Router 固有機能の取捨選択とすり合わせを考える
oukayuka
2
850
エンジニア向け採用ピッチ資料
inusan
0
160
つよそうにふるまい、つよい成果を出すのなら、つよいのかもしれない
irof
1
300
#kanrk08 / 公開版 PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実
bash0c7
1
370
既存デザインを変更せずにタップ領域を広げる方法
tahia910
1
240
AWS CDKの推しポイント 〜CloudFormationと比較してみた〜
akihisaikeda
3
310
アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介
andpad
0
260
Featured
See All Featured
Embracing the Ebb and Flow
colly
86
4.7k
Designing for humans not robots
tammielis
253
25k
Building an army of robots
kneath
306
45k
The Cult of Friendly URLs
andyhume
79
6.5k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
It's Worth the Effort
3n
185
28k
Producing Creativity
orderedlist
PRO
346
40k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
138
34k
Rebuilding a faster, lazier Slack
samanthasiow
81
9.1k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
A better future with KSS
kneath
239
17k
Transcript
ʙ͋Εͬʁ࡞ऀɾɾɾ͋Εͬʁʁʁฤʙ !QZBNB(.01FQBCP *OD 3VCZ8PVME$POGFSFODF OHY@NSVCZWʹ͓͚Δ ϊϯϒϩοΩϯάͳNSVCZ࣮ߦͷ ࣮ৄࡉ
γχΞɾϓϦϯγύϧΤϯδχΞ ࢁԼ!QZBNB ϗεςΟϯάࣄۀ෦νʔϑςΫχΧϧϦʔυ IUUQTUFOTOBQPODPN
ϗεςΟϯάࣄۀ &$ࢧԉࣄۀ ϋϯυϝΠυɾͦͷଞࣄۀ
ϩϦϙοϓʂϨϯλϧαʔόαʔϏεఏڙ։࢝ ϔςϜϧαʔϏεఏڙ։࢝ 1ࢁ͕ϖύϘʹೖࣾʂʂ̍ ݄ ࣛࣇౡݝग़ਫࢢʹ͓͍ͯ1ࢁരʂʂ̍
ݱࡏɾۀ ϜʔϜʔυϝΠϯαʔϏεఏڙ։࢝
45/4 -JOVY/444FSWFS TUOTKQ
45/4
ࠓ͢͜ͱ wOHY@NSVCZ wOHJOYͷجຊ wOHY@NSVCZWͷ՝ wOHY@NSVCZWʹ͓͚ΔϊϯϒϩοΩϯάॲཧ
લఏ wOHJOYͷΠϕϯτϞδϡʔϧFQPMMલఏͰ͠·͢ w3VCZͷΛ͠·͕͢ɺ3VCZߏจͷ͋·Γग़͖ͯ ·ͤΜ
OHY@NSVCZ "'BTUBOE.FNPSZ&⒏DJFOU8FC4FSWFS&YUFOTJPO.FDIBOJTN 6TJOH4DSJQUJOH-BOHVBHFNSVCZGPSOHJOY IUUQOHYNSVCZPSH
OHY@NSVCZWʹίϯτϦϏϡʔτ
None
OHY@NSVCZ NSVCZ@TTM@IBOETIBLF@IBOEMFS@DPEF TTMOHJOY44-OFX DFSUJpDBUF@EBUB'JMFSFBE QBUIUP\TTMTFSWFSOBNF^DSU LFZ@EBUB'JMFSFBE QBUIUP\TTMTFSWFSOBNF^LFZ TTMDFSUJpDBUF@EBUBDFSUJpDBUF@EBUB
TTMDFSUJpDBUF@LFZ@EBUBLFZ@EBUB OHJOYͷ͋ΒΏΔΠϕϯτʹϑοΫͯ͠ɺNSVCZͷίʔυΛ࣮ߦ͠ɺ ϓϥΨϒϧʹτϥϑΟοΫίϯτϩʔϧग़དྷΔ
ϖύϘͷࣄྫ ಈతূ໌ॻཧ ඦສυϝΠϯͷূ໌ॻΛ.Z42-Ͱཧ ίϯςϯπΩϟογϡ ΩϟογϡϙϦγʔΛ)551"1*ܦ༝Ͱऔಘ͠ɺOHJOYͷ Ωϟογϡͷ0/ɾ0''Λίϯτϩʔϧ
OHJOY NSVCZ
Πϕϯτۦಈ ඇಉظ*0 OHJOY
Πϕϯτۦಈ OHJOY FQPMM FWFOU FWFOU FWFOU DMJFOU DMJFOU DMJFOU BDDFQU
BDDFQU BDDFQU FQPMM@XBJU ଓϨεϙϯεΛ*0Πϕϯτͱͯ͠ॲཧ͢Δ IUUQTMJOVYKNPTEOKQIUNM-%1@NBOQBHFTNBOFQPMM@XBJUIUNM
ඇಉظ*0શͯϑΝΠϧͰ͋Δ OHJOY FQPMM FWFOU FWFOU FWFOU DMJFOU DMJFOU DMJFOU BDDFQU
BDDFQU BDDFQU FQPMM@XBJU ϑΝΠϧσΟεΫϦϓλͦΕͧΕΛϒϩοΫͤͣ FQPMMͰඇಉظʹ*0ॲཧΛߦ͏ GE GE GE
OHJOYXPSLFS OHJOY FQPMM FWFOU FWFOU FWFOU DMJFOU DMJFOU DMJFOU BDDFQU
BDDFQU BDDFQU FQPMM@XBJU ΫϥΠΞϯτ͔ΒͷϦΫΤετXPSLFS͕ॲཧ XPSLFS XPSLFS NBTUFS FQPMM@XBJU
OHY@NSVCZ OHJOY FQPMM FWFOU FWFOU FWFOU DMJFOU DMJFOU DMJFOU BDDFQU
BDDFQU BDDFQU FQPMM@XBJU )551ϦΫΤετ࣌ͷNSVCZ࣮ߦXPSLFSͰߦΘΕΔ XPSLFS XPSLFS NBTUFS MPDBUJPOIFBEFST\ NSVCZ@DPOUFOU@IBOEMFS@DPEF SOHJOY3FRVFTUOFX SDPOUFOU@UZQFUFYUIUNM OHJOYSQVUTIFBEFST\SIFBEFST@JOBMM^CSCS ^
OHY@NSVCZͷ՝ SFRVFTU SFRVFTU SFRVFTU NSVCZ NSVCZ NSVCZ SFTQPOTF SFTQPOTF SFTQPOTF
XPSLFS XPSLFS͋ͨΓͷNSVCZ࣮ߦͰඇಉظ*0͕ϒϩοΫ͞ΕΔ
ࠓͷओ SFRVFTU SFRVFTU SFRVFTU NSVCZ NSVCZ NSVCZ SFTQPOTF SFTQPOTF SFTQPOTF
XPSLFS ͜͏ͳͬͨʂʂ͍̍ͯ͏Λ͠·͢
Ϧιʔε͕͏·͘׆༻Ͱ͖ͳ͍έʔε container.boot! loop do break if container.boot? sleep 1000 end
OHY@NSVCZ͔ΒίϯςφϓϩηεΛىಈ͠ɺ ىಈྃΛTMFFQͰͭΑ͋͘Δॲཧ
՝Λղܾ͢ΔϊϯϒϩοΩϯάΠϯλʔϑΣʔε /HJOY"TZODTMFFQ /HJOY"TZOD)551TVC@SFRVFTU
/HJOY"TZODTMFFQ
/HJOY"TZODTMFFQ SFRVFTU SFRVFTU NSVCZ SFTQPOTF SFTQPOTF MPPQEP CSFBLJGDPOUBJOFSCPPU
/HJOY"TZODTMFFQ FOE NSVCZ TMFFQ TMFFQ࣌ʹNSVCZͷϒϩοΫΛ։์͢Δ
/HJOY"TZODTMFFQ wOHYFWFOUMPPQ wOHY@BEE@UJNFS w'JCFS
OHJOYFWFOUMPPQ pOEUJNFS FQPMM@XBJU FYFDFWFOU IBOEMFS FYFDUJNFS IBOEMFS ۙͰൃՐ͢ΔλΠϚʔΛ୳͢ *0ΠϕϯτΛͭ *0ΠϕϯτͷϋϯυϥΛ࣮ߦ͢Δ
λΠϚʔͷϋϯυϥΛ࣮ߦ͢Δ
OHJOYFWFOUIBOEMFS wOHJOYͰFWFOUʹIBOEMFSΛఆٛग़དྷΔ wUJNFSͷIBOEMFSίʔϧόοΫͷΑ͏ͳΠϝʔδ wϢʔβʔͷҙͷΦϒδΣΫτΛ֨ೲɺऔΓग़͢͜ͱ ͕Մೳ
OHY@BEE@UJNFS ev = (ngx_event_t *)p; ev->handler = ngx_mrb_timer_handler; ev->data =
re; ngx_add_timer(ev, (ngx_msec_t)timer); FWEBUBʹNSC@TUBUFͳͲ3VCZͷใΛอ࣋͠ɺ IBOEMFS࣮ߦ࣌ʹऔΓग़͠ɺ3VCZΛ࣮ߦ͢Δ
3VCZͷίϯςΩετͲ͏ͳΔ͔ʁ puts "1" Nginx::Async.sleep 1000 puts "2" /HJOY"TZODTMFFQ͕࣮ߦ͞Εɺ QVUT͕࣮ߦ͞Εͯ͠·͏ ˠ3VCZͷॲཧΛఀࢭ͢Δඞཁ͕͋Δ
'JCFS
'JCFS fiber = Fiber.new { puts 'Ruby is' Fiber.yield puts
'Good' } fiber.resume fiber.resume ͍ΘΏΔίϧʔνϯͰɺ'JCFSZJFMEͷ࣌Ͱ ॲཧΛఀࢭͤ͞Δ͜ͱ͕ग़དྷΔɻ 'JCFSSFTVNFʹΑͬͯॲཧΛ࠶։
3VCZJT (PPE
OHY@NSVCZ'JCFS *NBHF MPDBUJPOIFBEFST\ NSVCZ@DPOUFOU@IBOEMFS@DPEF QVUT /HJOY"TZODTMFFQ QVUT ^ MPDBUJPOIFBEFST\
NSVCZ@DPOUFOU@IBOEMFS@DPEF 'JCFSOFXEP QVUT /HJOY"TZODTMFFQ QVUT FOE 3VCZͷίʔυΛ'JCFSͰ҉తʹแΉ
OHY@NSVCZ'JCFS *NBHF EFG@OHY@NSC@QSFQBSF@pCFS OHJOY@IBOEMFS pCFS@IBOEMFS'JCFSOFX\OHJOY@IBOEMFSDBMM^ MBNCEBEP SFTVMUpCFS@IBOEMFSSFTVNF <pCFS@IBOEMFSBMJWF SFTVMU>
FOE FOE 'JCFSΛ͞Βʹ1SPDͰแΉ
/HJOY"TZODTMFFQ class Async class << self def sleep(*args) __sleep(*args) Fiber.yield
end end end @@TMFFQ UJNFS࡞Δϝιου Ͱ 'JCMFSΠϯελϯεΛ$ͷίϯςΩετʹ อଘ͠ɺOHJOYͷλΠϚʔϋϯυϥʔʹઃఆޙɺ 'JCFSZJFMEͰ3VCZΛఀࢭ
OHY@BEE@UJNFS OHY@NSVCZ@UJNFS @IBOEFS 'JCFSZJFME 'JCFSSFTVNF 'JCFSΦϒδΣΫτΛίʔϧόοΫؔͷϙΠϯλͱڞʹ λΠϚʔʹηοτ λΠϚʔηοτ࣌Ͱ3VCZͷίϯςΩετΛఀࢭ͠ɺOHJOYͷ ΠϕϯτϧʔϓΛ࠶։ λΠϚʔΠϕϯτൃՐ࣌ʹ࣮ߦ͞ΕɺλΠϚʔΠϕϯτ͔Β
3VCZͷίϯςΩετΛऔΓग़͢ 3VCZͷ࣮ߦΛ࠶։͢Δ /HJOY"TZOD4MFFQ
/HJOY"TZOD)551TVC@SFRVFTU
OHY@IUUQ@TVCSFRVFTU location / { # subrequest } location /subreqest {
puts "hello" } # http://localhost/ => hello ͋ΔϩέʔγϣϯʹདྷͨϦΫΤετΛ ଞͷϩέʔγϣϯʹϦΫΤετͨ݁͠ՌͰ Ԡ͢ΔΑ͏ͳ͍ํ
SFRVFTU SFRVFTU NSVCZ SFTQPOTF SFTQPOTF NSVCZ ϦΫΤετΛ͛ΔͱϒϩοΫΛ։์͠ɺ Ϩεϙϯε࣌ʹίʔϧόοΫΛड͚औΓ࠶։ TVCSFRFTU 3FRVFTU
3FTQPOTF /HJOY"TZOD)551TVC@SFRVFTU
/HJOY"TZOD)551TVC@SFRVFTU3FEJT location / { # subrequest /redis } location /redis
{ puts redis get key } 3FEJTͷϦΫΤετͪ࣌ؒ ֎෦"1*ΛOHY@NSVCZͰ࣮ߦ͢Δ Α͋͘Δέʔε
/HJOY"TZOD)551TVC@SFRVFTU def sub_request(location, query_param = nil) if query_param.is_a?(Hash) __sub_request(location, ::nginx::Utils....)
elsif query_param.is_a?(String) __sub_request(location, query_param) elsea __sub_request(location) end Fiber.yield end TMFFQͱಉ͘͡ɺ@@TVC@SFRVFTUͰ ίʔϧόοΫΛઃఆ͠ɺ'JCFSZJFME
/HJOY"TZOD)551TVC@SFRVFTU ps->handler = ngx_mrb_async_http_sub_request_done; ps->data = actx; if (ngx_http_subrequest(r, actx->uri,
args, &sr, ps, NGX_HTTP_SUBREQUEST_IN_MEMORY) != NGX_OK) { mrb_raise(mrb, E_RUNTIME_ERROR, "ngx_http_subrequest failed for http_sub_rquest method"); } ίʔϧόοΫΛઃఆ͠ɺαϒϦΫΤετΛ࣮ߦ͢Δ
/HJOY"TZOD)551TVC@SFRVFTU static ngx_int_t ngx_mrb_async_http_sub_request_done(ngx_http_request_t *sr, void *data, ngx_int_t rc) {
ngx_mrb_async_http_ctx_t *actx = data; ngx_mrb_reentrant_t *re = actx->re; ngx_http_mruby_ctx_t *ctx; re->r = sr->parent; ... ίʔϧόοΫͰฦ٫͞ΕΔOHY@IUUQ@SFRVFTU@Uߏମ˞͔Β αϒϦΫΤετͷϨεϙϯεϘσΟϔομ͕औಘͰ͖ͳ͍ ˞֤ΠϕϯτͰ࣋ͪճΒΕΔɺϦΫΤετͷใ
XBJUJOHTVCSFRVFTU pOBMJ[FCPEZpMUFS /HJOY"TZOD)551TVC@SFRVFTU NBJOSFRVFTU OHY@IUUQ@SFRVFTU@U TVCSFRVFTU OHY@IUUQ@SFRVFTU@U PUIFSFWFOU OHY@IUUQ@SFRVFTU@UNBJO pOJTISFRVFTU
NSVCZ αϒϦΫΤετͷϨεϙϯεɺϝΠϯϦΫΤετͷ ώʔϓʹॻ͍ͯ͋͛Δඞཁ͕͋Δ
/HJOY"TZOD)551TVC@SFRVFTU location /async_http_sub_request { mruby_rewrite_handler_code ' Nginx::Async::HTTP.sub_request "/sub_req_dst" res =
Nginx::Async::HTTP.last_response nginx.rputs res.body '; } Ϩεϙϯεͷड͚औΓϝΠϯϦΫΤετͷ(FUUFSΛ௨ͯ͠ɺ αϒϦΫΤετ͕ॻ͍ͨώʔϓͷΛऔಘ
ੑೳධՁ
IUUQTICNBUTVNPUPSKQFOUSZ
ଌఆڥ w.BD#PPL1SP.JE w$16()[*OUFM$PSFJ w.FNPSZ(# w7JSUVBM#PY w$16$PSF w.FNPSZ(# w046CVOUV9FOJBM
TMFFQNTFD SFUVSO MPDBUJPO" CMPDLJOH IUUQSFRVFTU MPDBUJPO# OPOCMPDLJOH IUUQSFRVFTU BC $
ab -n 10000 -c 100 http://127.0.0.1:58080/ PSJHJOʹ)551ϦΫΤετ͢Δڥ IUUQSFRVFTU IUUQSFRVFTU
OPOCMPDLJOH͕ഒఔߴͰ͋Δ CMPDLJOHIUUQSFRVFTU OPOCMPDLJOHIUUQSFRVFTU 3FRVFTUTQFSTFDPOE<TFD> NFBO 5JNFQFSSFRVFTU<NT> 5JNFQFSSFRVFTU<NT> 5SBOTGFSSBUF<,CZUFTTFD>SFDFJWFE 3FRVFTUTQFSTFDPOE<TFD>
NFBO 5JNFQFSSFRVFTU<NT> 5JNFQFSSFRVFTU<NT> 5SBOTGFSSBUF<,CZUFTTFD>SFDFJWFE
࠷ޙʹ
NSVCZ࠷ߴʂʂ̍ NSVCZʹΑͬͯΤϯδχΞͱͯ͠ɺ Ұஈਂ͘જΕΔΑ͏ʹͳͬͨ
5IBOLZPV ࠷৽ͷ࠾༻ใΛνΣοΫˠ !QC@SFDSVJU