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
    OHY@NSVCZWʹ͓͚Δ
    ϊϯϒϩοΩϯάͳNSVCZ࣮ߦͷ
    ࣮૷ৄࡉ

    View Slide

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

    View Slide

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

    View Slide

  4. ೥ ϩϦϙοϓʂϨϯλϧαʔόαʔϏεఏڙ։࢝


    ೥ ϔςϜϧαʔϏεఏڙ։࢝
    1ࢁ͕ϖύϘʹೖࣾʂʂ̍
    ೥݄೔
    ࣛࣇౡݝग़ਫࢢʹ͓͍ͯ1ࢁര஀ʂʂ̍
    ೥ ݱࡏɾ૑ۀ೥໨
    ϜʔϜʔυϝΠϯαʔϏεఏڙ։࢝

    View Slide

  5. 45/4
    -JOVY/444FSWFS
    TUOTKQ

    View Slide

  6. 45/4

    View Slide

  7. ࠓ೔࿩͢͜ͱ
    wOHY@NSVCZ
    wOHJOYͷجຊ
    wOHY@NSVCZWͷ՝୊
    wOHY@NSVCZWʹ͓͚ΔϊϯϒϩοΩϯάॲཧ

    View Slide

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

    View Slide

  9. OHY@NSVCZ
    "'BTUBOE.FNPSZ&⒏DJFOU8FC4FSWFS&YUFOTJPO.FDIBOJTN
    6TJOH4DSJQUJOH-BOHVBHFNSVCZGPSOHJOY
    IUUQOHYNSVCZPSH

    View Slide

  10. OHY@NSVCZWʹίϯτϦϏϡʔτ

    View Slide

  11. View Slide


  12. View Slide

  13. 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ͷίʔυΛ࣮ߦ͠ɺ
    ϓϥΨϒϧʹτϥϑΟοΫίϯτϩʔϧग़དྷΔ

    View Slide

  14. ϖύϘͷࣄྫ
    ಈతূ໌ॻ؅ཧ
    ਺ඦສυϝΠϯͷূ໌ॻΛ.Z42-Ͱ؅ཧ
    ίϯςϯπΩϟογϡ
    ΩϟογϡϙϦγʔΛ)551"1*ܦ༝Ͱऔಘ͠ɺOHJOYͷ
    Ωϟογϡͷ0/ɾ0''Λίϯτϩʔϧ

    View Slide

  15. OHJOY

    NSVCZ

    View Slide

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

    View Slide

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

    ઀ଓ΍ϨεϙϯεΛ*0Πϕϯτͱͯ͠ॲཧ͢Δ
    IUUQTMJOVYKNPTEOKQIUNM-%1@NBOQBHFTNBOFQPMM@XBJUIUNM

    View Slide

  18. ඇಉظ*0શͯ͸ϑΝΠϧͰ͋Δ
    OHJOY
    FQPMM
    FWFOU
    FWFOU
    FWFOU
    DMJFOU
    DMJFOU
    DMJFOU
    BDDFQU
    BDDFQU
    BDDFQU
    FQPMM@XBJU

    ϑΝΠϧσΟεΫϦϓλͦΕͧΕΛϒϩοΫͤͣ
    FQPMMͰඇಉظʹ*0ॲཧΛߦ͏
    GE
    GE
    GE

    View Slide

  19. OHJOYXPSLFS
    OHJOY
    FQPMM
    FWFOU
    FWFOU
    FWFOU
    DMJFOU
    DMJFOU
    DMJFOU
    BDDFQU
    BDDFQU
    BDDFQU
    FQPMM@XBJU

    ΫϥΠΞϯτ͔ΒͷϦΫΤετ͸XPSLFS͕ॲཧ
    XPSLFS
    XPSLFS
    NBTUFS
    FQPMM@XBJU

    View Slide

  20. 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

    ^

    View Slide

  21. OHY@NSVCZͷ՝୊
    SFRVFTU
    SFRVFTU
    SFRVFTU
    NSVCZ
    NSVCZ
    NSVCZ
    SFTQPOTF
    SFTQPOTF
    SFTQPOTF
    XPSLFS
    XPSLFS͋ͨΓͷNSVCZ࣮ߦͰඇಉظ*0͕ϒϩοΫ͞ΕΔ

    View Slide

  22. ࠓ೔ͷओ୊
    SFRVFTU
    SFRVFTU
    SFRVFTU
    NSVCZ
    NSVCZ
    NSVCZ
    SFTQPOTF
    SFTQPOTF
    SFTQPOTF
    XPSLFS
    ͜͏ͳͬͨʂʂ͍̍ͯ͏࿩Λ͠·͢

    View Slide

  23. Ϧιʔε͕͏·͘׆༻Ͱ͖ͳ͍έʔε
    container.boot!
    loop do
    break if container.boot?
    sleep 1000
    end
    OHY@NSVCZ͔ΒίϯςφϓϩηεΛىಈ͠ɺ
    ىಈ׬ྃΛTMFFQͰ଴ͭΑ͋͘Δॲཧ

    View Slide

  24. ՝୊Λղܾ͢ΔϊϯϒϩοΩϯάΠϯλʔϑΣʔε
    /HJOY"TZODTMFFQ
    /HJOY"TZOD)551TVC@SFRVFTU

    View Slide

  25. /HJOY"TZODTMFFQ

    View Slide

  26. /HJOY"TZODTMFFQ
    SFRVFTU
    SFRVFTU NSVCZ
    SFTQPOTF
    SFTQPOTF
    MPPQEP
    CSFBLJGDPOUBJOFSCPPU
    /HJOY"TZODTMFFQ
    FOE
    NSVCZ
    TMFFQ
    TMFFQ࣌ʹNSVCZͷϒϩοΫΛ։์͢Δ

    View Slide

  27. /HJOY"TZODTMFFQ
    wOHYFWFOUMPPQ
    wOHY@BEE@UJNFS
    w'JCFS

    View Slide

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

    View Slide

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

    View Slide

  30. 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Λ࣮ߦ͢Δ

    View Slide

  31. 3VCZͷίϯςΩετ͸Ͳ͏ͳΔ͔ʁ
    puts "1"
    Nginx::Async.sleep 1000
    puts "2"
    /HJOY"TZODTMFFQ͕࣮ߦ͞Εɺ
    QVUT͕࣮ߦ͞Εͯ͠·͏
    ˠ3VCZͷॲཧΛఀࢭ͢Δඞཁ͕͋Δ

    View Slide

  32. 'JCFS

    View Slide

  33. 'JCFS
    fiber = Fiber.new {
    puts 'Ruby is'
    Fiber.yield
    puts 'Good'
    }
    fiber.resume
    fiber.resume
    ͍ΘΏΔίϧʔνϯͰɺ'JCFSZJFMEͷ࣌఺Ͱ
    ॲཧΛఀࢭͤ͞Δ͜ͱ͕ग़དྷΔɻ
    'JCFSSFTVNFʹΑͬͯॲཧΛ࠶։

    View Slide

  34. 3VCZJT
    (PPE

    View Slide

  35. 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Ͱ҉໧తʹแΉ

    View Slide

  36. OHY@NSVCZ'JCFS *NBHF

    EFG@OHY@NSC@QSFQBSF@pCFS OHJOY@IBOEMFS

    pCFS@IBOEMFS'JCFSOFX\OHJOY@IBOEMFSDBMM^
    MBNCEBEP
    SFTVMUpCFS@IBOEMFSSFTVNF

    FOE
    FOE
    'JCFSΛ͞Βʹ1SPDͰแΉ

    View Slide

  37. /HJOY"TZODTMFFQ
    class Async
    class << self
    def sleep(*args)
    __sleep(*args)
    Fiber.yield
    end
    end
    end
    @@TMFFQ UJNFS࡞Δϝιου
    ಺Ͱ
    'JCMFSΠϯελϯεΛ$ͷίϯςΩετʹ
    อଘ͠ɺOHJOYͷλΠϚʔϋϯυϥʔʹઃఆޙɺ
    'JCFSZJFMEͰ3VCZΛఀࢭ

    View Slide

  38. OHY@BEE@UJNFS
    OHY@NSVCZ@UJNFS
    @IBOEFS
    'JCFSZJFME
    'JCFSSFTVNF
    'JCFSΦϒδΣΫτΛίʔϧόοΫؔ਺ͷϙΠϯλͱڞʹ
    λΠϚʔʹηοτ
    λΠϚʔηοτ࣌఺Ͱ3VCZͷίϯςΩετΛఀࢭ͠ɺOHJOYͷ
    ΠϕϯτϧʔϓΛ࠶։
    λΠϚʔΠϕϯτൃՐ࣌ʹ࣮ߦ͞ΕɺλΠϚʔΠϕϯτ͔Β
    3VCZͷίϯςΩετΛऔΓग़͢
    3VCZͷ࣮ߦΛ࠶։͢Δ
    /HJOY"TZOD4MFFQ

    View Slide

  39. /HJOY"TZOD)551TVC@SFRVFTU

    View Slide

  40. OHY@IUUQ@TVCSFRVFTU
    location / {
    # subrequest
    }
    location /subreqest {
    puts "hello"
    }
    # http://localhost/
    => hello
    ͋ΔϩέʔγϣϯʹདྷͨϦΫΤετΛ
    ଞͷϩέʔγϣϯʹϦΫΤετͨ݁͠ՌͰ
    Ԡ౴͢ΔΑ͏ͳ࢖͍ํ

    View Slide

  41. SFRVFTU
    SFRVFTU NSVCZ
    SFTQPOTF
    SFTQPOTF
    NSVCZ
    ϦΫΤετΛ౤͛ΔͱϒϩοΫΛ։์͠ɺ
    Ϩεϙϯε࣌ʹίʔϧόοΫΛड͚औΓ࠶։
    TVCSFRFTU
    3FRVFTU 3FTQPOTF
    /HJOY"TZOD)551TVC@SFRVFTU

    View Slide

  42. /HJOY"TZOD)551TVC@SFRVFTU3FEJT
    location / {
    # subrequest /redis
    }
    location /redis {
    puts redis get key
    }
    3FEJTͷϦΫΤετ଴ͪ࣌ؒ΍
    ֎෦"1*ΛOHY@NSVCZͰ࣮ߦ͢Δ
    Α͋͘Δέʔε

    View Slide

  43. /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

    View Slide

  44. /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");
    }
    ίʔϧόοΫΛઃఆ͠ɺαϒϦΫΤετΛ࣮ߦ͢Δ

    View Slide

  45. /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ߏ଄ମ˞͔Β͸
    αϒϦΫΤετͷϨεϙϯεϘσΟ΍ϔομ͕औಘͰ͖ͳ͍
    ˞֤ΠϕϯτͰ࣋ͪճΒΕΔɺϦΫΤετͷ৘ใ

    View Slide

  46. XBJUJOHTVCSFRVFTU
    pOBMJ[FCPEZpMUFS
    /HJOY"TZOD)551TVC@SFRVFTU
    NBJOSFRVFTU
    OHY@IUUQ@SFRVFTU@U

    TVCSFRVFTU
    OHY@IUUQ@SFRVFTU@U

    PUIFSFWFOU
    OHY@IUUQ@SFRVFTU@UNBJO
    pOJTISFRVFTU
    NSVCZ
    αϒϦΫΤετͷϨεϙϯε͸ɺϝΠϯϦΫΤετͷ
    ώʔϓʹॻ͍ͯ͋͛Δඞཁ͕͋Δ

    View Slide

  47. /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Λ௨ͯ͠ɺ
    αϒϦΫΤετ͕ॻ͍ͨώʔϓͷ஋Λऔಘ

    View Slide

  48. ੑೳධՁ

    View Slide

  49. IUUQTICNBUTVNPUPSKQFOUSZ

    View Slide

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

    View Slide

  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

    View Slide

  52. OPOCMPDLJOH͕ഒఔ౓ߴ଎Ͱ͋Δ
    CMPDLJOHIUUQSFRVFTU OPOCMPDLJOHIUUQSFRVFTU
    3FRVFTUTQFSTFDPOE<TFD> NFBO

    5JNFQFSSFRVFTU
    5JNFQFSSFRVFTU
    5SBOTGFSSBUF<,CZUFTTFD>SFDFJWFE
    3FRVFTUTQFSTFDPOE<TFD> NFBO

    5JNFQFSSFRVFTU
    5JNFQFSSFRVFTU
    5SBOTGFSSBUF<,CZUFTTFD>SFDFJWFE

    View Slide

  53. ࠷ޙʹ

    View Slide

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

    View Slide

  55. 5IBOLZPV
    ࠷৽ͷ࠾༻৘ใΛνΣοΫˠ !QC@SFDSVJU

    View Slide