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
700
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.3k
事業を差別化する技術を生み出す技術
pyama86
4
1.7k
Re:Define 可用性を支える モニタリング、パフォーマンス最適化、そしてセキュリティ
pyama86
9
8.5k
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.8k
Tuning GraphQL on Rails
pyama86
2
2.1k
ttlcacheのここがスゴい
pyama86
1
170
クラウドサービスの 利用コストを削減する技術 - 円安の真南風を感じて -
pyama86
3
640
実践ARMアーキテクチャ移行
pyama86
2
2.5k
リモートワーク時代の守護神 PHP開発者のためのセキュリティ強化術
pyama86
3
1.3k
Other Decks in Programming
See All in Programming
DynamoDBは怖くない!〜テーブル設計の勘所とテスト戦略〜
hyamazaki
0
180
No Install CMS戦略 〜 5年先を見据えたフロントエンド開発を考える / no_install_cms
rdlabo
0
460
ZeroETLで始めるDynamoDBとS3の連携
afooooil
0
150
あのころの iPod を どうにか再生させたい
orumin
2
1.6k
대규모 트래픽을 처리하는 프론트 개발자의 전략
maryang
0
120
新世界の理解
koriym
0
130
Reactの歴史を振り返る
tutinoko
1
170
Streamlitで実現できるようになったこと、実現してくれたこと
ayumu_yamaguchi
2
280
物語を動かす行動"量" #エンジニアニメ
konifar
12
2.9k
あなたとJIT, 今すぐアセンブ ル
sisshiki1969
0
400
管你要 trace 什麼、bpftrace 用下去就對了 — COSCUP 2025
shunghsiyu
0
290
構文解析器入門
ydah
7
2k
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
6.5k
Intergalactic Javascript Robots from Outer Space
tanoku
272
27k
Into the Great Unknown - MozCon
thekraken
40
2k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3k
Become a Pro
speakerdeck
PRO
29
5.5k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Facilitating Awesome Meetings
lara
54
6.5k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Adopting Sorbet at Scale
ufuk
77
9.5k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
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