Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ngx_mruby v2における ノンブロッキングなmruby実行の実装詳細

ngx_mruby v2における ノンブロッキングなmruby実行の実装詳細

RubyWouldConference2018にてngx_mruby v2のノンブロッキングインターフェースについてトークしました。

Kazuhiko Yamashita

November 05, 2018
Tweet

More Decks by Kazuhiko Yamashita

Other Decks in Programming

Transcript

  1. ʙ͋Εͬʁ࡞ऀɾɾɾ͋Εͬʁʁʁฤʙ !QZBNB(.01FQBCP *OD 3VCZ8PVME$POGFSFODF [email protected]Wʹ͓͚Δ ϊϯϒϩοΩϯάͳNSVCZ࣮ߦͷ ࣮૷ৄࡉ

  2. γχΞɾϓϦϯγύϧΤϯδχΞ ࢁԼ࿨඙!QZBNB ϗεςΟϯάࣄۀ෦νʔϑςΫχΧϧϦʔυ IUUQTUFOTOBQPODPN

  3. ϗεςΟϯάࣄۀ &$ࢧԉࣄۀ ϋϯυϝΠυɾͦͷଞࣄۀ

  4. ೥ ϩϦϙοϓʂϨϯλϧαʔόαʔϏεఏڙ։࢝ ೥ ೥ ೥ ϔςϜϧαʔϏεఏڙ։࢝ 1ࢁ͕ϖύϘʹೖࣾʂʂ̍ ೥݄೔ ࣛࣇౡݝग़ਫࢢʹ͓͍ͯ1ࢁര஀ʂʂ̍ ೥

    ݱࡏɾ૑ۀ೥໨ ϜʔϜʔυϝΠϯαʔϏεఏڙ։࢝
  5. 45/4 -JOVY/444FSWFS TUOTKQ

  6. 45/4

  7. ࠓ೔࿩͢͜ͱ [email protected] wOHJOYͷجຊ [email protected]Wͷ՝୊ [email protected]Wʹ͓͚ΔϊϯϒϩοΩϯάॲཧ

  8. લఏ wOHJOYͷΠϕϯτϞδϡʔϧ͸FQPMMલఏͰ࿩͠·͢ w3VCZͷ࿩Λ͠·͕͢ɺ3VCZߏจͷ࿩͸͋·Γग़͖ͯ ·ͤΜ

  9. [email protected] "'BTUBOE.FNPSZ&⒏DJFOU8FC4FSWFS&YUFOTJPO.FDIBOJTN 6TJOH4DSJQUJOH-BOHVBHFNSVCZGPSOHJOY IUUQOHYNSVCZPSH

  10. [email protected]WʹίϯτϦϏϡʔτ

  11. None
  12. 

  13. [email protected] [email protected]@[email protected]@DPEF TTMOHJOY44-OFX [email protected]'JMFSFBE QBUIUP\TTMTFSWFSOBNF^DSU  [email protected]'JMFSFBE QBUIUP\TTMTFSWFSOBNF^LFZ  TTM[email protected][email protected]

    TTM[email protected]@EBUB[email protected]  OHJOYͷ͋ΒΏΔΠϕϯτʹϑοΫͯ͠ɺNSVCZͷίʔυΛ࣮ߦ͠ɺ ϓϥΨϒϧʹτϥϑΟοΫίϯτϩʔϧग़དྷΔ
  14. ϖύϘͷࣄྫ ಈతূ໌ॻ؅ཧ ਺ඦສυϝΠϯͷূ໌ॻΛ.Z42-Ͱ؅ཧ ίϯςϯπΩϟογϡ ΩϟογϡϙϦγʔΛ)551"1*ܦ༝Ͱऔಘ͠ɺOHJOYͷ Ωϟογϡͷ0/ɾ0''Λίϯτϩʔϧ

  15. OHJOY  NSVCZ

  16. Πϕϯτۦಈ ඇಉظ*0 OHJOY

  17. Πϕϯτۦಈ OHJOY FQPMM FWFOU FWFOU FWFOU DMJFOU DMJFOU DMJFOU BDDFQU

    BDDFQU BDDFQU [email protected]  ઀ଓ΍ϨεϙϯεΛ*0Πϕϯτͱͯ͠ॲཧ͢Δ IUUQTMJOVYKNPTEOKQIUNM-%[email protected]QBHFTNBO[email protected]IUNM
  18. ඇಉظ*0શͯ͸ϑΝΠϧͰ͋Δ OHJOY FQPMM FWFOU FWFOU FWFOU DMJFOU DMJFOU DMJFOU BDDFQU

    BDDFQU BDDFQU [email protected]  ϑΝΠϧσΟεΫϦϓλͦΕͧΕΛϒϩοΫͤͣ FQPMMͰඇಉظʹ*0ॲཧΛߦ͏ GE GE GE
  19. OHJOYXPSLFS OHJOY FQPMM FWFOU FWFOU FWFOU DMJFOU DMJFOU DMJFOU BDDFQU

    BDDFQU BDDFQU [email protected]  ΫϥΠΞϯτ͔ΒͷϦΫΤετ͸XPSLFS͕ॲཧ XPSLFS XPSLFS NBTUFS [email protected] 
  20. [email protected] OHJOY FQPMM FWFOU FWFOU FWFOU DMJFOU DMJFOU DMJFOU BDDFQU

    BDDFQU BDDFQU [email protected]  )551ϦΫΤετ࣌ͷNSVCZ࣮ߦ΋XPSLFSͰߦΘΕΔ XPSLFS XPSLFS NBTUFS MPDBUJPOIFBEFST\ [email protected]@[email protected] SOHJOY3FRVFTUOFX S[email protected]UFYUIUNM OHJOYSQVUTIFBEFST\S[email protected]BMM^CSCS  ^
  21. [email protected]ͷ՝୊ SFRVFTU SFRVFTU SFRVFTU NSVCZ NSVCZ NSVCZ SFTQPOTF SFTQPOTF SFTQPOTF

    XPSLFS XPSLFS͋ͨΓͷNSVCZ࣮ߦͰඇಉظ*0͕ϒϩοΫ͞ΕΔ
  22. ࠓ೔ͷओ୊ SFRVFTU SFRVFTU SFRVFTU NSVCZ NSVCZ NSVCZ SFTQPOTF SFTQPOTF SFTQPOTF

    XPSLFS ͜͏ͳͬͨʂʂ͍̍ͯ͏࿩Λ͠·͢
  23. Ϧιʔε͕͏·͘׆༻Ͱ͖ͳ͍έʔε container.boot! loop do break if container.boot? sleep 1000 end

    [email protected]͔ΒίϯςφϓϩηεΛىಈ͠ɺ ىಈ׬ྃΛTMFFQͰ଴ͭΑ͋͘Δॲཧ
  24. ՝୊Λղܾ͢ΔϊϯϒϩοΩϯάΠϯλʔϑΣʔε /HJOY"TZODTMFFQ /HJOY"TZOD)551[email protected]

  25. /HJOY"TZODTMFFQ

  26. /HJOY"TZODTMFFQ SFRVFTU SFRVFTU NSVCZ SFTQPOTF SFTQPOTF MPPQEP  CSFBLJGDPOUBJOFSCPPU 

     /HJOY"TZODTMFFQ FOE NSVCZ TMFFQ TMFFQ࣌ʹNSVCZͷϒϩοΫΛ։์͢Δ
  27. /HJOY"TZODTMFFQ wOHYFWFOUMPPQ [email protected]@UJNFS w'JCFS

  28. OHJOYFWFOUMPPQ pOEUJNFS [email protected] FYFDFWFOU IBOEMFS FYFDUJNFS IBOEMFS ௚ۙͰൃՐ͢ΔλΠϚʔΛ୳͢ *0ΠϕϯτΛ଴ͭ *0ΠϕϯτͷϋϯυϥΛ࣮ߦ͢Δ

    λΠϚʔͷϋϯυϥΛ࣮ߦ͢Δ
  29. OHJOYFWFOUIBOEMFS wOHJOYͰ͸FWFOUʹIBOEMFSΛఆٛग़དྷΔ wUJNFSͷIBOEMFS͸ίʔϧόοΫͷΑ͏ͳΠϝʔδ wϢʔβʔͷ೚ҙͷΦϒδΣΫτΛ֨ೲɺऔΓग़͢͜ͱ ͕Մೳ

  30. [email protected]@UJNFS ev = (ngx_event_t *)p; ev->handler = ngx_mrb_timer_handler; ev->data =

    re; ngx_add_timer(ev, (ngx_msec_t)timer); FWEBUBʹ[email protected]ͳͲ3VCZͷ৘ใΛอ࣋͠ɺ IBOEMFS࣮ߦ࣌ʹऔΓग़͠ɺ3VCZΛ࣮ߦ͢Δ
  31. 3VCZͷίϯςΩετ͸Ͳ͏ͳΔ͔ʁ puts "1" Nginx::Async.sleep 1000 puts "2" /HJOY"TZODTMFFQ͕࣮ߦ͞Εɺ QVUT͕࣮ߦ͞Εͯ͠·͏ ˠ3VCZͷॲཧΛఀࢭ͢Δඞཁ͕͋Δ

  32. 'JCFS

  33. 'JCFS fiber = Fiber.new { puts 'Ruby is' Fiber.yield puts

    'Good' } fiber.resume fiber.resume ͍ΘΏΔίϧʔνϯͰɺ'JCFSZJFMEͷ࣌఺Ͱ ॲཧΛఀࢭͤ͞Δ͜ͱ͕ग़དྷΔɻ 'JCFSSFTVNFʹΑͬͯॲཧΛ࠶։
  34. 3VCZJT (PPE

  35. [email protected]'JCFS *NBHF MPDBUJPOIFBEFST\ [email protected]@[email protected] QVUT /HJOY"TZODTMFFQ QVUT  ^ MPDBUJPOIFBEFST\

    [email protected]@[email protected] 'JCFSOFXEP QVUT /HJOY"TZODTMFFQ QVUT FOE  3VCZͷίʔυΛ'JCFSͰ҉໧తʹแΉ
  36. [email protected]'JCFS *NBHF EFG@[email protected]@[email protected] [email protected]  [email protected]'JCFSOFX\[email protected]DBMM^ MBNCEBEP SFTVMU[email protected]SFTVNF <[email protected]BMJWF SFTVMU>

    FOE FOE 'JCFSΛ͞Βʹ1SPDͰแΉ
  37. /HJOY"TZODTMFFQ class Async class << self def sleep(*args) __sleep(*args) Fiber.yield

    end end end @@TMFFQ UJNFS࡞Δϝιου ಺Ͱ 'JCMFSΠϯελϯεΛ$ͷίϯςΩετʹ อଘ͠ɺOHJOYͷλΠϚʔϋϯυϥʔʹઃఆޙɺ 'JCFSZJFMEͰ3VCZΛఀࢭ
  38. [email protected]@UJNFS [email protected]@UJNFS @IBOEFS 'JCFSZJFME 'JCFSSFTVNF 'JCFSΦϒδΣΫτΛίʔϧόοΫؔ਺ͷϙΠϯλͱڞʹ λΠϚʔʹηοτ λΠϚʔηοτ࣌఺Ͱ3VCZͷίϯςΩετΛఀࢭ͠ɺOHJOYͷ ΠϕϯτϧʔϓΛ࠶։ λΠϚʔΠϕϯτൃՐ࣌ʹ࣮ߦ͞ΕɺλΠϚʔΠϕϯτ͔Β

    3VCZͷίϯςΩετΛऔΓग़͢ 3VCZͷ࣮ߦΛ࠶։͢Δ /HJOY"TZOD4MFFQ
  39. /HJOY"TZOD)551[email protected]

  40. [email protected]@TVCSFRVFTU location / { # subrequest } location /subreqest {

    puts "hello" } # http://localhost/ => hello ͋ΔϩέʔγϣϯʹདྷͨϦΫΤετΛ ଞͷϩέʔγϣϯʹϦΫΤετͨ݁͠ՌͰ Ԡ౴͢ΔΑ͏ͳ࢖͍ํ
  41. SFRVFTU SFRVFTU NSVCZ SFTQPOTF SFTQPOTF NSVCZ ϦΫΤετΛ౤͛ΔͱϒϩοΫΛ։์͠ɺ Ϩεϙϯε࣌ʹίʔϧόοΫΛड͚औΓ࠶։ TVCSFRFTU 3FRVFTU

    3FTQPOTF /HJOY"TZOD)551[email protected]
  42. /HJOY"TZOD)551[email protected]3FEJT location / { # subrequest /redis } location /redis

    { puts redis get key } 3FEJTͷϦΫΤετ଴ͪ࣌ؒ΍ ֎෦"1*Λ[email protected]Ͱ࣮ߦ͢Δ Α͋͘Δέʔε
  43. /HJOY"TZOD)551[email protected] 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ͱಉ͘͡ɺ@@[email protected]Ͱ ίʔϧόοΫΛઃఆ͠ɺ'JCFSZJFME
  44. /HJOY"TZOD)551[email protected] 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"); } ίʔϧόοΫΛઃఆ͠ɺαϒϦΫΤετΛ࣮ߦ͢Δ
  45. /HJOY"TZOD)551[email protected] 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; ... ίʔϧόοΫͰฦ٫͞ΕΔ[email protected]@[email protected]ߏ଄ମ˞͔Β͸ αϒϦΫΤετͷϨεϙϯεϘσΟ΍ϔομ͕औಘͰ͖ͳ͍ ˞֤ΠϕϯτͰ࣋ͪճΒΕΔɺϦΫΤετͷ৘ใ
  46. XBJUJOHTVCSFRVFTU pOBMJ[FCPEZpMUFS /HJOY"TZOD)551[email protected] NBJOSFRVFTU [email protected]@[email protected] TVCSFRVFTU [email protected]@[email protected] PUIFSFWFOU [email protected]@[email protected]NBJO pOJTISFRVFTU

    NSVCZ αϒϦΫΤετͷϨεϙϯε͸ɺϝΠϯϦΫΤετͷ ώʔϓʹॻ͍ͯ͋͛Δඞཁ͕͋Δ
  47. /HJOY"TZOD)551[email protected] 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Λ௨ͯ͠ɺ αϒϦΫΤετ͕ॻ͍ͨώʔϓͷ஋Λऔಘ
  48. ੑೳධՁ

  49. IUUQTICNBUTVNPUPSKQFOUSZ

  50. ଌఆ؀ڥ w.BD#PPL1SP.JE w$16()[*OUFM$PSFJ w.FNPSZ(# w7JSUVBM#PY w$16$PSF w.FNPSZ(# w046CVOUV9FOJBM

  51. TMFFQNTFD SFUVSO MPDBUJPO" CMPDLJOH IUUQSFRVFTU MPDBUJPO# OPOCMPDLJOH IUUQSFRVFTU BC $

    ab -n 10000 -c 100 http://127.0.0.1:58080/ PSJHJOʹ)551ϦΫΤετ͢Δ؀ڥ IUUQSFRVFTU IUUQSFRVFTU
  52. OPOCMPDLJOH͕ഒఔ౓ߴ଎Ͱ͋Δ CMPDLJOHIUUQSFRVFTU OPOCMPDLJOHIUUQSFRVFTU 3FRVFTUTQFSTFDPOE<TFD> NFBO  5JNFQFSSFRVFTU<NT> 5JNFQFSSFRVFTU<NT> 5SBOTGFSSBUF<,CZUFTTFD>SFDFJWFE 3FRVFTUTQFSTFDPOE<TFD>

    NFBO  5JNFQFSSFRVFTU<NT> 5JNFQFSSFRVFTU<NT> 5SBOTGFSSBUF<,CZUFTTFD>SFDFJWFE
  53. ࠷ޙʹ

  54. NSVCZ࠷ߴʂʂ̍ NSVCZʹΑͬͯΤϯδχΞͱͯ͠ɺ Ұஈਂ͘જΕΔΑ͏ʹͳͬͨ

  55. 5IBOLZPV ࠷৽ͷ࠾༻৘ใΛνΣοΫˠ [email protected]