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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Kazuhiko Yamashita
November 05, 2018
Programming
720
1
Share
ngx_mruby v2における ノンブロッキングなmruby実行の実装詳細
RubyWouldConference2018にてngx_mruby v2のノンブロッキングインターフェースについてトークしました。
Kazuhiko Yamashita
November 05, 2018
More Decks by Kazuhiko Yamashita
See All by Kazuhiko Yamashita
タクシーアプリ『GO』の バックエンド開発のおける AI利活用と若者のすべて
pyama86
3
1.7k
継続的な負荷検証を目指して
pyama86
3
1.5k
成長期における、 ユーザー領域の複雑さと 整備の進め方
pyama86
1
580
Stay Hacker 〜九州で生まれ、Perlに出会い、コミュニティで育つ〜
pyama86
2
6.2k
Managing Database Migrations in Go Backend Systems
pyama86
0
470
新しい職場の CI が 20 分かかっていたらあなたならどうする?
pyama86
2
1.5k
事業を差別化する技術を生み出す技術
pyama86
4
2.2k
Re:Define 可用性を支える モニタリング、パフォーマンス最適化、そしてセキュリティ
pyama86
9
11k
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
2k
Other Decks in Programming
See All in Programming
ECR拡張スキャンでSBOMを収集して サプライチェーン攻撃の影響調査を 爆速で終わらせてみた
akihisaikeda
2
200
今さら聞けないCancellationToken
htkym
0
200
Inside Stream API
skrb
1
210
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.1k
柔軟なPDFレイアウトエディタを支える型システム設計 — Discriminated UnionとConditional Typeの実践
minako__ph
4
620
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
120
バックエンドにElysiaJSを採用して気付いた、良い点・悪い点
wanko_it
1
180
The Arts and Crafts of Work in the AI Era — Toward Mastery in Software Development
kuranuki
0
450
Sans tests, vos agents ne sont pas fiables
nabondance
0
160
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
7
2.4k
Old Dog, New Tricks: The Java 25 Reinvention - JNation
bazlur_rahman
0
130
GitHub Copilot CLIのいいところ
htkym
2
1.1k
Featured
See All Featured
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
310
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
200
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
The Limits of Empathy - UXLibs8
cassininazir
1
340
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
450
Prompt Engineering for Job Search
mfonobong
0
320
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
How GitHub (no longer) Works
holman
316
150k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Evolving SEO for Evolving Search Engines
ryanjones
0
200
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