ハチャメチャに叩く

271fad8d53cd1f12f2b4b6d38e3d7bd3?s=47 uzulla
July 13, 2018

 ハチャメチャに叩く

【非公式】PHPカンファレンス 2018 関西 前夜祭
https://dbstudychugoku.connpass.com/event/92337/

271fad8d53cd1f12f2b4b6d38e3d7bd3?s=128

uzulla

July 13, 2018
Tweet

Transcript

  1. ϋνϟϝνϟʹhttp(s) ͰԥΓ͍ͨ

  2. @uzulla

  3. ઌ೔Swooleͷ࿩Λ͠·͕ͨ͠ • https:/ /speakerdeck.com/uzulla/zui-jin- meruhuomukaitenaimeruhuomaniyoru-tiyotutodakebian-watuta- ying-phpfalsemeruhuomu-falseohua-fu-ti-zui-jin- swoolegatafalsesiidesu • ʢ௕͍…ʣ •

    ʢuzulla swoole speakerdeckͰݕࡧʣ • ඇಉظɺcoroutine౳ͷ࿩͕͋·ΓͰ͖ͳ͔ͬͨͷͰ • ͦͷؔ࿈
  4. ਓ͸ϋνϟϝνϟʹʢAPIͱ͔Λʣୟ͖͍ͨ • PHPͰ΋ͲΜͲΜୟ͖͍ͨ • Ϋϩʔϧ͍ͨͨ͠Ί • ྲྀߦͷϚΠΫϩφϯτΧͰ୔ࢁAPIΛୟ͘ඞཁ • ૘շײΛಘΔͨΊ

  5. • ͔͠͠PHP͸ʮ஗͍ʯ(Β͍͠) !

  6. • Կ͕஗͍͔ʁ! • http͸ʮऔಘ͢Δ଴ͪ࣌ؒʯ͕ࢧ഑త • ௚ྻͷಉظॲཧͰ͸ͦͷؒͳʹ΋Ͱ͖ͳ͍ʂ " • ଞͷݴޠͰ͸؆୯ʹʢʁʣϚϧνεϨουʹͨ͠Γ͢Δʢཁ ग़య#ʣ

    • ͔͠͠PHP͸ϚϧνεϨουɺϚϧνϓϩηε͸Ή͔͍ͣ͠ ʢཁग़య#ʣ
  7. Ͳ͏͢Δ͔ʁ • ඇಉظͩʂ • PHPͷඇಉظ͸݁ߏྺ࢙͕͋Δ(ओ؍) • ʢඇಉظI/OɺϊϯϒϩοΩϯάI/OɺଟॏԽI/Oͱ͔৭ʑ͋Δ ͕ɺ͜͜Ͱ͸Ұॹͨ͘ʹඇಉظͱ͓͖ͯ͠·͢ʣ

  8. ʮඇಉظʯͱ͸ʁ • I/OॲཧதʹϘʔͬͱͤͣɺଞͷ͜ͱΛ΍ΕΔ • ฒྻॲཧͰ͸ͳ͍ɺʢਅͷʣϚϧνεϨουͰ͸ͳ͍ • ͳΜΒ͔c֦ுΛೖΕͳ͍ͱCPUෛՙ͕ߴ͍ • ex: ev,uv,event,swoole

    • ૉखͰ৮Δͷ͸େมͳͷͰϑϨʔϜϫʔΫ͕ॏཁ • ex: reactPHP,swoole,amp౳
  9. None
  10. None
  11. None
  12. None
  13. None
  14. ༨ஊ curl_multi Ͱ͍͍ͷͰ͸ʁ • ࠷ॳʹʮNݸऔಘʯΈ͍ͨʹͳΔͷͰɺ̍ͭऴΘΓ࣍ୈҰͭى ಈͱ͔Ͱ͖ͳ͍ • ༻్ʹΑΔ͕ɺྫ͑͹ΫϩʔϥͰ͸ඞཁ • selectͷѻ͍͸೉͍͠…

    • ʢͦ΋ͦ΋curl_* ࣗମ͕೉͍͠ʣ • ʢͲ͜ʹͰ΋ೖ͍ͬͯΔʢʁʣͷ͸࠷ߴʣ
  15. ʮͱ͍͏͜ͱͰswooleͰඇಉظͩʂʯ • ຺བྷ͸লུ͠·͢ɻ • ʮͳͥPHPͳͷ͔ɺదࡐదॴ͕ඞཁͰ͸ʁʁʯ • ʮࠓ೔PHPҎ֎ͷ࿩ͯ͠΋͔ͨ͠ͳ͍Ͱ͠ΐ…ʯ

  16. swooleʹ͓͚Δهड़ํࣜ • callbackํࣜ • coroutineํࣜ

  17. • callbackํࣜ • ΠϕϯτۦಈΒ͍͠ॻ͖ํ • JSͬΆ͍ • ຊདྷ͕ͪ͜ΒͳͷͰɺݫີʹௐ੔͠΍͍͢ • ωετ΍෼அ͕૿͑ΔͷͰগʑಡΈͮΒ͍

  18. • coroutineํࣜ • ී௨ͷίʔυͬΆ͍ɺಡΈ΍͍͢ɺָ • (PHPͷ) δΣωϨʔλͬΆ͍ • ͪΐͬͱͨ͠ແବ͕Ͱ͖΍͍͢ •

    ৭ʑӅṭ͞Ε͍ͯΔͷͰɺٯʹ೴಺࣮ߦͮ͠Β͍͜ͱ΋ • ࠓճ͸ͪ͜Β
  19. • swoole͸࠷ۙcoroutineํࣜਪ͠ • swoole͸go()Λ͔ͭ͏ͱɺઐ༻؀ڥʢΠϕϯτϧʔϓͳͲʣ֎Ͱ ΋ίϧʔνϯΛಈ͔ͤΔ • ʢͷͰָɻׂ͕͜͜ͱॏཁͳͷ͕ͩɺൺֱʹͳΔ͠આ໌͕௕ ͘ͳΔͷͰলུʣ

  20. coroutineͷྑ͍ͱ͜Ζ • ;ͭʔͷίʔυͰ͸ɺAPI΍DBΞΫηεΛ͍͔ͭ͘ॱ൪ʹߦ͏ • coroutine͸ී௨(௚ྻ)ʹॻ͚Δ • callbackํࣜ͸ωετ(ؔ਺Ͱ෼ׂ)͠ͳ͚Ε͹ͳΒͳ͍ • PromiseΛ͔ͭ͑͹ฏୱʹ͸Ͱ͖Δ͕ɺείʔϓͷ෼ׂ͸͞Ε Δ

  21. ͱ͍͏͜ͱͰαϯϓϧίʔυ • coroutineํࣜ • ʮwhileͰ΍ΔͷɺͲ͏ͳͷʁʯ ʮsleepΛௐ੔͢Ε͹࣮༻Ͱ͠ΐ…ʢͲ͏͔ͳʁʣʯ

  22. • ͓ࢼ͢͠Δਓ͸ͪ͜Β͔ΒͲ͏ͧ • https:/ /github.com/uzulla/sample-co-get

  23. <?php // Ұൠతͳ௚ྻऔಘίʔυ const MAX_REQ = 10; // نఆॲཧ਺ $req_num

    = 0; while (1) { echo "."; // نఆॲཧ਺Λ௒͑ͨͷͰऴྃ if ($req_num >= MAX_REQ) { break; } // औಘ $req_num++; $_ = file_get_contents("http://example.jp"); }
  24. • 1req2ඵ͔͔ΔAPIΛ10ճऔಘͩͱ… real 0m20.199s user 0m0.089s sys 0m0.067s

  25. <?php // coroutineͰ͔͍ͯΈΔ go(function () { $now_worker_num = 0; $req_num

    = 0; while (1) { echo "."; co::sleep(0.001); // εέδϡʔϥͷͨΊʹ // نఆॲཧूΛ௒͑ͨͷͰऴྃ if ($req_num >= MAX_REQ) { break; } // ىಈதͷίϧʔνϯ͕نఆ਺ʹୡ͍ͯ͠ͳ͚Ε͹௥Ճىಈɺ // ʢنఆϫʔΧʔ਺ͳΒىಈͤͣɺϧʔϓઌ಄΁ʣ if ($now_worker_num >= MAX_WORKER_NUM) { continue; }
  26. // while (1) { // ... // go()಺ͷΫϩʔδϟ͕ίϧʔνϯͱͯ͠εέδϡʔϥʹొ࿥ go(function ()

    use (&$now_worker_num, &$req_num) { $req_num++; $now_worker_num++; $http = new \Swoole\Coroutine\Http\Client( "http://example.jp", 80); $http->get('/'); $_ = $http->body; $now_worker_num--; }); // ্ه׬ྃΛ଴ͨͣʹൈ͚Δ } });
  27. real 0m4.187s user 0m0.267s sys 0m0.523s

  28. • 1req2ඵ͔͔ΔAPIΛ10ճऔಘ͢Δͷʹ • ʢಉظʣ20ඵ->ʢඇಉظʣ4ඵ • ಉ࣌5઀ଓͩͱ̎ճ • ಉ࣌10ʹͳΒҰׅͰऴΘΔͷͰ̎ඵʹ • ʢ…ͳΔ͜ͱ΋͋Δʣ

  29. coroutineཧղצॴ • go()ͰίϧʔνϯΛ࡞੒ͯ͠ʮޙͰ࣮ߦϦετʯʹ௥Ճ͠ʢεέ δϡʔϧ͞ΕΔʣɺޙͰ࣮ߦ͢Δ • ઐ༻ʹ࡞ΒΕͨؔ਺Ҏ֎͸ඇಉظʹ͸ͳΒͳ͍

  30. εέδϡʔϧ…ʁ • ֓೦ਤͰͬ͘͟Γઆ໌͍ͨ͠

  31. None
  32. None
  33. None
  34. None
  35. None
  36. None
  37. None
  38. • ʮεέδϡʔϧͬͯΫϩʔδϟΛฒ΂ସ͍͑ͯΔ͚ͩͳͷͰ ͸ʁʯʮ͜͜Ͱ͸͋Δҙຯਖ਼ղͰ͢ʯ • (ࠓճ͸set/getDeferͷ࿩͸͠·ͤΜ) • ʢͪΌΜͱཧղ͢ΔͨΊʹίʔυΛಡΉͳΒɺreactPHPͳͲͷ ίʔυ͸ൺֱతಡΈ΍͍͢ʢSwoole͸CͳͷͰ…ʣʣ

  39. • Ͳ͔͜ΒͰ΋ࣗ༝ʹεΠον͞ΕΔ༁Ͱ͸ͳ͍ • ओʹIO΍sleepͳͲɺ໭ͯ͠ҙຯ͕͋ΔॴͰ౉͞ΕΔ • ͦ͏͍͏;͏ʹSwoole͕औΓ࢓੾͍ͬͯΔ

  40. • JSΈ͍ͨʹؔ਺୯ҐͰࣗಈతʹ੾Γସ͑͞Εͳ͍ͷͰ஫ҙ • ʮͳΜ͔ίϧʔνϯ͕ಈ͔ΜʂແݶϧʔϓʂϩοΫʂʯͱ͍ ͏࣌͸େମ͜Ε • ׳ΕΔ·Ͱ͸ࢥͬͨ௨Γͷ࣮ߦλΠϛϯάʢεέδϡʔϦϯ άʣʹͳΒͳ͍͜ͱ΋͋Δ • ඞཁͳΒɺखಈͰco::sleepͳͲΛೖΕͨΓ͢Δ

    • ׳ΕΔ·Ͱ͸ʮͳΜͰಈ͔ͳ͍Μͩ…ʯͱࢥ͏͜ͱ΋ ->׳ΕΑ͏ʂ
  41. ·ͱΊ • ʮඇಉظ͸͋Μ·Γා͘ͳ͍ʯ • γϯϓϧʹॻ͖΍͘͢ಡΈ΍͍͢ͷ͕ʢSwooleͷʣ Coroutineʢओ؍ʣ • ͲΜͲΜAPIͳͲΛୟ͍ͯճΓ·͠ΐ͏ʂ

  42. ຊ౰ͷ(?)·ͱΊ • file_get_contentsͰे෼ͳΒɺͦ͏͠·͠ΐ͏ • ʮfile_get_contentsͰ଎౓͕ͨΓͳ͍༻్ͱ͸…͏͝͝…ʯ • ʮඇಉظͰ͏·͘΍Ε͹ඵؒXXXXճୟ͘͜ͱ΋ເͰ͸ͳ ͍ʂʯ • →

    ࣄ݅ʹͳΔ • ʮඇಉظͱ͔ɺ୭͕ϝϯς͢ΔΜͩ…ʯ • ʢ ચ೴ ҭ੒͍ͯ͜͠͏ʣ
  43. ࠓ೔͸࿩͞ͳ͔࣮ͬͨࡍʹϋνϟϝνϟʹୟͨ͘ Ίʹॏཁͳॴ • DNSΩϟογϡɺkeep-aliveɺλΠϜΞ΢τ&ϦτϥΠɺಈతε ϩοτϦϯάɺchanͳͲͰͷσʔλड͚౉͠ɺDefer • ʮຊ౰ʹඇಉظ͕ඞཁͳॴͱ͸Ͳ͔͜ʁʯ • ॏ͍݁Ռॲཧ͕ඞཁͳΒϚϧνίΞ͕׆͔ͤΔͷͰϚϧνϓ ϩηεͷ΄͏͕ྑ͍

    • ʮϚϧνϓϩηεʴඇಉظͩʂʯʮγϯϓϧͱ͸…ʯ
  44. go()͝ਗ਼ௌ͍͖ͨͩ͋Γ͕ͱ͏͍͟͝ ·ͨ͠ɻ

  45. • ͕࣌ؒ༨Ε͹ҎԼ

  46. coroutine͕ಡΈ΍͍͢ɺͱ͸ʁ • ʢҎԼ࣮ࡍʹಈ͔͍ͯ͠ΔίʔυͰ͸ͳ͍Ͱ͕͢ʣ

  47. go(function () { $http = new Co\Http\Client("http://example.jp", 80); $http->get('/api.json'); $data

    = json_decode($http->body); $id = $data[0]['id']; $http->get('/api.json?id='.$id); $data = json_decode($http->body); $child_id = $data[0]['child_id']; $http->get('/api.json?child_id='.$child_id); $data = json_decode($http->body); echo $data['title']; //-> });
  48. $client = new Swoole\Http2\Client("example.jp", 80); $client->get("/", function ($o) use($client) {

    $data = json_decode($o->body); $id = $data[0]['id']; $client->get("/api.json?id=".$id, function ($o) use($client) { $data = json_decode($o->body); $child_id = $data[0]['child_id']; $client->get("/api.json?child_id=".$id, function ($o) use($client) { $data = json_decode($o->body); echo $data['title']; //---------> } } });
  49. 3ճϦΫΤετΛͳ͛Δͱ… # coro //-> (1Πϯσϯτ # cb //---------> (3Πϯσϯτ

  50. • ී௨ɺ͍͔ͭ͘ͷAPI΍DBΞΫηεΛॱ൪ʹߦ͏ • coroutine͸ී௨(௚ྻ)ʹॻ͚Δ • ίʔϧόοΫํࣜ͸ωετ(ؔ਺Ͱ෼ׂ)͠ͳ͚Ε͹ͳΒͳ͍ • PromiseΛ͔ͭ͑͹ฏୱʹ͸Ͱ͖Δ͕ɺείʔϓͷ෼ׂ͸͞Ε Δ

  51. see also • https:/ /wiki.swoole.com/wiki/page/p-coroutinehttpclient.html • https:/ /github.com/swoole/swoole-src/tree/master/examples/ coroutine •

    https:/ /wiki.swoole.com/wiki/page/752.html • https:/ /wiki.swoole.com/wiki/page/784.html • https:/ /github.com/eaglewu/swoole-ide-helper • https:/ /www.swoole.com/ • https:/ /www.swoole.co.uk/docs/modules/swoole-async-http-client