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
ハチャメチャに叩く
Search
uzulla
July 13, 2018
Programming
1
1.7k
ハチャメチャに叩く
【非公式】PHPカンファレンス 2018 関西 前夜祭
https://dbstudychugoku.connpass.com/event/92337/
uzulla
July 13, 2018
Tweet
Share
More Decks by uzulla
See All by uzulla
似たもの同士のPerlとPHP
uzulla
1
170
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
130
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
210
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
150
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
2.2k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
4
1k
PHPerが ISUCONでやるべき事
uzulla
1
1.1k
開発生産性は上がらない - N Ways to Reduce Development Productivity
uzulla
1
270
test is not a job
uzulla
1
520
Other Decks in Programming
See All in Programming
ML.NETで始める機械学習
ymd65536
0
220
クリーンアーキテクチャから見る依存の向きの大切さ
shimabox
4
920
PHPカンファレンス名古屋2025 タスク分解の試行錯誤〜レビュー負荷を下げるために〜
soichi
1
650
Generating OpenAPI schema from serializers throughout the Rails stack - Kyobashi.rb #5
envek
1
330
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
14
4.5k
未経験でSRE、はじめました! 組織を支える役割と軌跡
curekoshimizu
1
120
『GO』アプリ バックエンドサーバのコスト削減
mot_techtalk
0
150
AIプログラミング雑キャッチアップ
yuheinakasaka
13
3.1k
Ça bouge du côté des animations CSS !
goetter
2
140
Visual StudioのGitHub Copilotでいろいろやってみる
tomokusaba
1
200
Rails アプリ地図考 Flush Cut
makicamel
1
130
Rubyで始める関数型ドメインモデリング
shogo_tksk
0
130
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Bash Introduction
62gerente
611
210k
The Invisible Side of Design
smashingmag
299
50k
Embracing the Ebb and Flow
colly
84
4.6k
Bootstrapping a Software Product
garrettdimon
PRO
306
110k
Git: the NoSQL Database
bkeepers
PRO
427
65k
Being A Developer After 40
akosma
89
590k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Fontdeck: Realign not Redesign
paulrobertlloyd
83
5.4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Transcript
ϋνϟϝνϟʹhttp(s) ͰԥΓ͍ͨ
@uzulla
ઌSwooleͷΛ͠·͕ͨ͠ • https:/ /speakerdeck.com/uzulla/zui-jin- meruhuomukaitenaimeruhuomaniyoru-tiyotutodakebian-watuta- ying-phpfalsemeruhuomu-falseohua-fu-ti-zui-jin- swoolegatafalsesiidesu • ʢ͍…ʣ •
ʢuzulla swoole speakerdeckͰݕࡧʣ • ඇಉظɺcoroutineͷ͕͋·ΓͰ͖ͳ͔ͬͨͷͰ • ͦͷؔ࿈
ਓϋνϟϝνϟʹʢAPIͱ͔Λʣୟ͖͍ͨ • PHPͰͲΜͲΜୟ͖͍ͨ • Ϋϩʔϧ͍ͨͨ͠Ί • ྲྀߦͷϚΠΫϩφϯτΧͰࢁAPIΛୟ͘ඞཁ • շײΛಘΔͨΊ
• ͔͠͠PHPʮ͍ʯ(Β͍͠) !
• Կ͕͍͔ʁ! • httpʮऔಘ͢Δͪ࣌ؒʯ͕ࢧత • ྻͷಉظॲཧͰͦͷؒͳʹͰ͖ͳ͍ʂ " • ଞͷݴޠͰ؆୯ʹʢʁʣϚϧνεϨουʹͨ͠Γ͢Δʢཁ ग़య#ʣ
• ͔͠͠PHPϚϧνεϨουɺϚϧνϓϩηεΉ͔͍ͣ͠ ʢཁग़య#ʣ
Ͳ͏͢Δ͔ʁ • ඇಉظͩʂ • PHPͷඇಉظ݁ߏྺ࢙͕͋Δ(ओ؍) • ʢඇಉظI/OɺϊϯϒϩοΩϯάI/OɺଟॏԽI/Oͱ͔৭ʑ͋Δ ͕ɺ͜͜ͰҰॹͨ͘ʹඇಉظͱ͓͖ͯ͠·͢ʣ
ʮඇಉظʯͱʁ • I/OॲཧதʹϘʔͬͱͤͣɺଞͷ͜ͱΛΕΔ • ฒྻॲཧͰͳ͍ɺʢਅͷʣϚϧνεϨουͰͳ͍ • ͳΜΒ͔c֦ுΛೖΕͳ͍ͱCPUෛՙ͕ߴ͍ • ex: ev,uv,event,swoole
• ૉखͰ৮ΔͷେมͳͷͰϑϨʔϜϫʔΫ͕ॏཁ • ex: reactPHP,swoole,amp
None
None
None
None
None
༨ஊ curl_multi Ͱ͍͍ͷͰʁ • ࠷ॳʹʮNݸऔಘʯΈ͍ͨʹͳΔͷͰɺ̍ͭऴΘΓ࣍ୈҰͭى ಈͱ͔Ͱ͖ͳ͍ • ༻్ʹΑΔ͕ɺྫ͑ΫϩʔϥͰඞཁ • selectͷѻ͍͍͠…
• ʢͦͦcurl_* ࣗମ͕͍͠ʣ • ʢͲ͜ʹͰೖ͍ͬͯΔʢʁʣͷ࠷ߴʣ
ʮͱ͍͏͜ͱͰswooleͰඇಉظͩʂʯ • ຺བྷলུ͠·͢ɻ • ʮͳͥPHPͳͷ͔ɺదࡐదॴ͕ඞཁͰʁʁʯ • ʮࠓPHPҎ֎ͷ͔ͯͨ͠͠ͳ͍Ͱ͠ΐ…ʯ
swooleʹ͓͚Δهड़ํࣜ • callbackํࣜ • coroutineํࣜ
• callbackํࣜ • ΠϕϯτۦಈΒ͍͠ॻ͖ํ • JSͬΆ͍ • ຊདྷ͕ͪ͜ΒͳͷͰɺݫີʹௐ͍͢͠ • ωετஅ͕૿͑ΔͷͰগʑಡΈͮΒ͍
• coroutineํࣜ • ී௨ͷίʔυͬΆ͍ɺಡΈ͍͢ɺָ • (PHPͷ) δΣωϨʔλͬΆ͍ • ͪΐͬͱͨ͠ແବ͕Ͱ͖͍͢ •
৭ʑӅṭ͞Ε͍ͯΔͷͰɺٯʹ࣮ߦͮ͠Β͍͜ͱ • ࠓճͪ͜Β
• swoole࠷ۙcoroutineํࣜਪ͠ • swoolego()Λ͔ͭ͏ͱɺઐ༻ڥʢΠϕϯτϧʔϓͳͲʣ֎Ͱ ίϧʔνϯΛಈ͔ͤΔ • ʢͷͰָɻׂ͕͜͜ͱॏཁͳͷ͕ͩɺൺֱʹͳΔ͠આ໌͕ ͘ͳΔͷͰলུʣ
coroutineͷྑ͍ͱ͜Ζ • ;ͭʔͷίʔυͰɺAPIDBΞΫηεΛ͍͔ͭ͘ॱ൪ʹߦ͏ • coroutineී௨(ྻ)ʹॻ͚Δ • callbackํࣜωετ(ؔͰׂ)͠ͳ͚ΕͳΒͳ͍ • PromiseΛ͔ͭ͑ฏୱʹͰ͖Δ͕ɺείʔϓͷׂ͞Ε Δ
ͱ͍͏͜ͱͰαϯϓϧίʔυ • coroutineํࣜ • ʮwhileͰΔͷɺͲ͏ͳͷʁʯ ʮsleepΛௐ͢Ε࣮༻Ͱ͠ΐ…ʢͲ͏͔ͳʁʣʯ
• ͓ࢼ͢͠Δਓͪ͜Β͔ΒͲ͏ͧ • https:/ /github.com/uzulla/sample-co-get
<?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"); }
• 1req2ඵ͔͔ΔAPIΛ10ճऔಘͩͱ… real 0m20.199s user 0m0.089s sys 0m0.067s
<?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; }
// 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--; }); // ্هྃΛͨͣʹൈ͚Δ } });
real 0m4.187s user 0m0.267s sys 0m0.523s
• 1req2ඵ͔͔ΔAPIΛ10ճऔಘ͢Δͷʹ • ʢಉظʣ20ඵ->ʢඇಉظʣ4ඵ • ಉ࣌5ଓͩͱ̎ճ • ಉ࣌10ʹͳΒҰׅͰऴΘΔͷͰ̎ඵʹ • ʢ…ͳΔ͜ͱ͋Δʣ
coroutineཧղצॴ • go()ͰίϧʔνϯΛ࡞ͯ͠ʮޙͰ࣮ߦϦετʯʹՃ͠ʢεέ δϡʔϧ͞ΕΔʣɺޙͰ࣮ߦ͢Δ • ઐ༻ʹ࡞ΒΕͨؔҎ֎ඇಉظʹͳΒͳ͍
εέδϡʔϧ…ʁ • ֓೦ਤͰͬ͘͟Γઆ໌͍ͨ͠
None
None
None
None
None
None
None
• ʮεέδϡʔϧͬͯΫϩʔδϟΛฒସ͍͑ͯΔ͚ͩͳͷͰ ʁʯʮ͜͜Ͱ͋Δҙຯਖ਼ղͰ͢ʯ • (ࠓճset/getDeferͷ͠·ͤΜ) • ʢͪΌΜͱཧղ͢ΔͨΊʹίʔυΛಡΉͳΒɺreactPHPͳͲͷ ίʔυൺֱతಡΈ͍͢ʢSwooleCͳͷͰ…ʣʣ
• Ͳ͔͜ΒͰࣗ༝ʹεΠον͞ΕΔ༁Ͱͳ͍ • ओʹIOsleepͳͲɺͯ͠ҙຯ͕͋ΔॴͰ͞ΕΔ • ͦ͏͍͏;͏ʹSwoole͕औΓ͍ͬͯΔ
• JSΈ͍ͨʹؔ୯ҐͰࣗಈతʹΓସ͑͞Εͳ͍ͷͰҙ • ʮͳΜ͔ίϧʔνϯ͕ಈ͔ΜʂແݶϧʔϓʂϩοΫʂʯͱ͍ ͏࣌େମ͜Ε • ׳ΕΔ·Ͱࢥͬͨ௨Γͷ࣮ߦλΠϛϯάʢεέδϡʔϦϯ άʣʹͳΒͳ͍͜ͱ͋Δ • ඞཁͳΒɺखಈͰco::sleepͳͲΛೖΕͨΓ͢Δ
• ׳ΕΔ·ͰʮͳΜͰಈ͔ͳ͍Μͩ…ʯͱࢥ͏͜ͱ ->׳ΕΑ͏ʂ
·ͱΊ • ʮඇಉظ͋Μ·Γා͘ͳ͍ʯ • γϯϓϧʹॻ͖͘͢ಡΈ͍͢ͷ͕ʢSwooleͷʣ Coroutineʢओ؍ʣ • ͲΜͲΜAPIͳͲΛୟ͍ͯճΓ·͠ΐ͏ʂ
ຊͷ(?)·ͱΊ • file_get_contentsͰेͳΒɺͦ͏͠·͠ΐ͏ • ʮfile_get_contentsͰ͕ͨΓͳ͍༻్ͱ…͏͝͝…ʯ • ʮඇಉظͰ͏·͘ΕඵؒXXXXճୟ͘͜ͱເͰͳ ͍ʂʯ • →
ࣄ݅ʹͳΔ • ʮඇಉظͱ͔ɺ୭͕ϝϯς͢ΔΜͩ…ʯ • ʢ ચ ҭ͍ͯ͜͠͏ʣ
ࠓ͞ͳ͔࣮ͬͨࡍʹϋνϟϝνϟʹୟͨ͘ Ίʹॏཁͳॴ • DNSΩϟογϡɺkeep-aliveɺλΠϜΞτ&ϦτϥΠɺಈతε ϩοτϦϯάɺchanͳͲͰͷσʔλड͚͠ɺDefer • ʮຊʹඇಉظ͕ඞཁͳॴͱͲ͔͜ʁʯ • ॏ͍݁Ռॲཧ͕ඞཁͳΒϚϧνίΞ͕׆͔ͤΔͷͰϚϧνϓ ϩηεͷ΄͏͕ྑ͍
• ʮϚϧνϓϩηεʴඇಉظͩʂʯʮγϯϓϧͱ…ʯ
go()͝ਗ਼ௌ͍͖ͨͩ͋Γ͕ͱ͏͍͟͝ ·ͨ͠ɻ
• ͕࣌ؒ༨ΕҎԼ
coroutine͕ಡΈ͍͢ɺͱʁ • ʢҎԼ࣮ࡍʹಈ͔͍ͯ͠ΔίʔυͰͳ͍Ͱ͕͢ʣ
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']; //-> });
$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']; //---------> } } });
3ճϦΫΤετΛͳ͛Δͱ… # coro //-> (1Πϯσϯτ # cb //---------> (3Πϯσϯτ
• ී௨ɺ͍͔ͭ͘ͷAPIDBΞΫηεΛॱ൪ʹߦ͏ • coroutineී௨(ྻ)ʹॻ͚Δ • ίʔϧόοΫํࣜωετ(ؔͰׂ)͠ͳ͚ΕͳΒͳ͍ • PromiseΛ͔ͭ͑ฏୱʹͰ͖Δ͕ɺείʔϓͷׂ͞Ε Δ
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