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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Kazuhiko Yamashita
November 05, 2018
Programming
1
710
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
Stay Hacker 〜九州で生まれ、Perlに出会い、コミュニティで育つ〜
pyama86
2
5.7k
Managing Database Migrations in Go Backend Systems
pyama86
0
170
新しい職場の CI が 20 分かかっていたらあなたならどうする?
pyama86
2
1.5k
事業を差別化する技術を生み出す技術
pyama86
4
2k
Re:Define 可用性を支える モニタリング、パフォーマンス最適化、そしてセキュリティ
pyama86
9
10k
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.9k
Tuning GraphQL on Rails
pyama86
2
2.6k
ttlcacheのここがスゴい
pyama86
1
230
クラウドサービスの 利用コストを削減する技術 - 円安の真南風を感じて -
pyama86
3
700
Other Decks in Programming
See All in Programming
AIコーディングの理想と現実 2026 | AI Coding: Expectations vs. Reality 2026
tomohisa
0
1.1k
手戻りゼロ? Spec Driven Developmentとは@KAG AI week
tmhirai
1
170
AI時代のソフトウェア開発でも「人が仕様を書く」から始めよう-医療IT現場での実践とこれから
koukimiura
0
140
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
290
Agentic AI: Evolution oder Revolution
mobilelarson
PRO
0
110
Swift ConcurrencyでよりSwiftyに
yuukiw00w
0
250
Codexに役割を持たせる 他のAIエージェントと組み合わせる実務Tips
o8n
3
1.1k
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
260
浮動小数の比較について
kishikawakatsumi
0
380
Rで始めるML・LLM活用入門
wakamatsu_takumu
0
170
Go Conference mini in Sendai 2026 : Goに新機能を提案し実装されるまでのフロー徹底解説
yamatoya
0
530
LangChain4jとは一味違うLangChain4j-CDI
kazumura
1
150
Featured
See All Featured
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.4k
AI: The stuff that nobody shows you
jnunemaker
PRO
3
360
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
The Pragmatic Product Professional
lauravandoore
37
7.2k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
69
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
140
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.4k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
130
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.8k
Side Projects
sachag
455
43k
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