at 全然野菜(PHPCon Fukuoka 2018 非公式 前々夜祭) 20min talk https://pepabo.connpass.com/event/85144/
࠷ۙϝʔϧϑΥʔϜ͔͍ͯͳ͍ϝʔϧϑΥʔϚʔʹΑΔɺͪΐͬͱ͚ͩมΘͬͨҰԠPHPͷϝʔϧϑΥʔϜʢʁʣͷ͓෭ ࠷ۙswoole͕ͨͷ͍͠Ͱ͢
View Slide
• uzulla• ౦ژീԦࢠ͔Β͖·ͨ͠• ࠷ۙؾʹͳΔͷnginx unit
• ୈҰষ ࣄྫͱ͔ϕϯνͱ͔• ୈೋষ easy-swooleͷհ• େࡾএ
ࣄྫͱ͔ϕϯνͱ͔
͋Δͷࣄྫ• ಥવͷMOSUCON
MO-ney gaSUCO-shi sikaN-ai
MO-SUCO-N• ʮීஈͱஈҧ͍ͷΞΫηε͕͘Δͧʂ͔͠͠༧ࢉͰ·ͤΜʯ• ʮ͑ͬʯ
ྫʢ͋͘·Ͱྫʣ• ΩϟϯϖʔϯͷϝʔϧϑΥʔϜ• ʮϓϨθϯτCPʂ͝Ԡื͓ͪͯ͠·͢ʂʯ• ʮഔମʯͰଧͭͷͰɺҰؾʹདྷΔ• XXXrpsʙXXXXrps• ʢ͔͠͠༧ࢉͳ͍ʣ
• !ϢʔβʔؾܰʹϦϩʔυͳ͞Δ• "͍ͱπΠʔτ͞ΕͯɺౖΒΕΔ• #ͬ͞͞ͱฦ͚ͩ͢Ͱ͘͢͝มΘΔ• $εύΠΫ͍͔ͭऴΘΔͷͰɺҰॠ͑ΒΕΕউͪ• %ҰൃͷΩϟϯϖʔϯͳͷͰɺϝϯςͳ͍• &(ͱݟ͔͚ͤͯԿճΔࣄΑ͋͘Δ)
࣮ࡍPHP͕ʢׂͱʣ͔ͳ͍ࣄҊ• !preforkͷΈʢ΄΅ʣಉظॲཧͷPHP• nginx+php-fpmͩͱ͍ͩͿϚγ͕ͩɺApache+PHPࢮ• ࣌ؒଳʹΑͬͯڱଳҬͳϞόΠϧ૬खݫ͠Ί• !ΞΫηεຖʹશ෦ΛॳظԽ(ಛʹॏྔڃFW)• "ΞΫηε͕ڈΕΔ• #จݴमਖ਼ʹ࠶ىಈ͕͍Βͳ͍ʢॏཁʣ
࣌ؒͷ͔͔ΔॲཧΛͳ͍ͨ͘͠…• ֎෦APIͷΞΫηε• DBͷอଘ• …ͳͤ͘ͳ͍
• …ͱ͍͏͜ͱΛͲ͏ʹ͔͍ͨ͠• ……PHPͰʂʂ- ----• !ʮͦͦPHP͡Όͳ͍΄͏͕Α͍ͷͰʁʯ• ʮ·͋PHPerͳͷͰ…ʯ• !ʮࣄΛબ͍͍ͷͰʁʯ• ʮʯ
ͷํ๏͍Ζ͍Ζ͋Δ͕• ฒΔʁ -> ͓͕ۚͳ͍• ཁ݅Λม͑Δʁ -> ͓٬͞Μ͕NO• nginx + php-fpm + ૉPHPʁ -> ී௨͗͢Δʢʁʣ
ͱ͍͏͜ͱͰຊ• ʮ͔͔ͤͬͩ͘ΒԶswooleΛબͿͥʂʯ• ͱ͍͏͜ͱͰɺswooleͰΜͩΒͲ͏ͳΔͷʁͱ͍͏Λ͠·͢ɻ
αϯϓϧͱϕϯν
αϯϓϧίʔυ• ϝΞυΛݕূͯ͠DBʹอଘ͢ΔϝʔϧϑΥʔϜʢʁʣ• https://github.com/uzulla/easyswoole-sample• swoole൛ͱɺී௨ʹಈ͘൛ಉࠝ
• ʮԠื૯ʯԠืΛcount()ͯ͠දࣔ• ͨͩ͠ɺ̑ඵຖͷूܭ
• ϝΞυ͕ͳͦ͞͏ͳΒɺԠืྃ• ϝΞυଥੑݕূͷͨΊʹɺDNSΛҾ͍͍ͯΔ
ϕϯνϚʔΫ− બखհ- nginx + swoole- nginx + php-fpm
ςετ༻ڥ• ͪΐͬͱݹ͍MBP্ͷLinux VM• Parallels• Ubuntu 18
php (ڞ௨ɺ΄΅aptͰ͍Εͨ··)• PHP 7.2.6• opcache• xdebugͳͲແ͠• swoole֦ுswooleςετ࣌ͷΈ• (cliʹͷΈ֦ுΛϩʔυʣ
nginx (ڞ௨ɺ΄΅aptͰ͍Εͨ··)• worker_processes auto;• worker_connections 768;• gzip on;• tcp_nopush on;• tcp_nodelay on;• keepalive_timeout 65;
php-fpmʢൺֱ༻ʣ• FW slim 3• fpmઃఆ• pm = static• pm.max_children = 8• fastcgi unix socketଓ
swoole• swoole࠷৽൛ʴFWͱͯ͠easyswoole• ϫʔΧʔઃఆ• worker_num 8• max_resquest 50000• fastcgi unix socketଓ
࣮ଌ
ϕϯν̍• / (ϑΥʔϜ)Λճ͢ɺrpsΛܭଌ• wrk -c {N} -t 8 -d 10s -R 100000 http://{host}/• ಉ࣌ଓΛมԽ͍ͤͯ͘͞(c͕1ͷ࣌ͷΈɺt1)• ̎ճճͯ͠ߴ͍ํΛ࠾༻• Τϥʔ͕ͰͨΒ0ѻ͍
root@ubu:~/wrk2# ./wrk -c 1 -t 1 -d 10s -R 100000 http://127.0.0.1/Running 10s test @ http://127.0.0.1/1 threads and 1 connectionsThread Stats Avg Stdev Max +/- StdevLatency 5.13s 2.83s 9.95s 58.97%Req/Sec -nan -nan 0.00 0.00%4022 requests in 10.00s, 2.14MB readRequests/sec: 402.19Transfer/sec: 218.75KB
N php-fpm swoole1 402 253050 946 5782100 931 5429150 Τϥʔ 5335200 - 5994500 - 66121000 - Τϥʔ
ϕϯν̎• /post (อଘ)Λճ͢ɺrpsΛܭଌ• ab -c {N} -n 1000 -p postdata -m POST -T "application/x-www-form-urlencoded" http://{host}/post• ಉ࣌ଓΛมԽ͍ͤͯ͘͞• ̎ճճͯ͠ߴ͍ํΛ࠾༻• Τϥʔ͕ͰͨΒ0ѻ͍• (͕ࠩϠό͗͢ΔͷͰDNS͍߹ΘͤΛൈ͍ͯ͋Γ·͢)
N php-fpm swoole1 110 30310 412 477100 408 514150 Τϥʔ 537200 520400 540
• 500Ҏ্ɺab͕ΤϥʔΛు͍ͨͷͰ…
ࢀߟه helloworldϕϯν• wrk -c {N} -t 8 -d 10s -R 100000 http://{host}/hello• ୯ʹʮhelloʯ͚ͩΛฦ͢ɺయܕతͳʮϕϯν൪ʯίʔυ• ͖ͬΓݴͬͯҙຯͳ͍͆
N php-fpm swoole1 948 318750 1984 5935100 1909 7303150 Τϥʔ 6649200 7649500 8915
ࣄྫɾϕϯν·ͱΊ• ݟͯͷ௨Γɺଟॏଓ͕૿͑ͨΒ͕ࠩ͋Γ·͢ɻ• Write͕ೖΔͱɺϩδοΫʹඞཁͳ͕͔͔࣌ؒΔͷͰɺ྆ऀͷࠩॖ·Δ• php-fpmϓϩηεΛ૿͢ͱվળ͢Δࣄ͋Δ͕ɺ࣮ߦίετ্͕Δ• BacklogΛ;͢ͱόοϑΝʹͳΔ͕ɺΓ͍͔ͭ٧·Δ
• readʹ͍ͭͯαϯϓϧίʔυͷߏతʹswoole͕ζϧ͍ॴ͋Γ·͢• swooleርͰ݁ߏҧ͏͠Ͷɺৄ͓͘͠खݩͰࢼͯ͠Έ͍ͯͩ͘͞• ʮؾ߹Λ͍Εͯͭ͘Εʯɺͬͱੑೳ͕͋Δͣʢ͔ͦ͜͠͠·ͰखؒΛ͔͚Δͷ͔ʁʣ• ʮͱ͜ΖͰɺ͜ΕϝʔϧϑΥʔϜͳͷ͔ʁʯʮ࣮ࡍʹmailgunͱΈ߹ΘͤΔΜͰ͚͢Ͳɺ·͋ͦͷ͔ΘΓʹdnsΫΤϦ͍Εͯ͋Γ·͢…ʯ
͜ͷࠩ…• swooleͷྗʂ• …ͱ·Ͱ͍͑ͳ͍͚ͲɺϩδοΫ͕ϔϏʔͰͳ͚Εswooleͷ΄͏͕ଟগ͍ɻ• rps͕ࡾܻ͑ΔͳΒɺ༗ҙ• ٯʹɺ1ܻ2ܻͩͱେࠩͳ͍
• ଟগ͍ͱͯ͠ɺ͜Ε͕ʮͷ͍͢͝େมʯͩͬͨΒҙຯ͕ͳ͍• ࢲ͕͔͚ͯɺօ͞Μ͕͔͚ͳ͚Εҙຯͳ͍• झຯͰ͔͔ͭ͑͠ͳ͍ͳΒʢࢲ͕͍͍͚Ͳʣօ͞Μʹҙຯͳ͍ʢ͔ʣ• ଞͷΠϕϯτۦಈࣜϑϨʔϜϫʔΫͩͱ݁ߏେม• ͱ͍͏͜ͱͰɺeasyswooleͷհʹҠΓ·͢
• ʢ͜͜·Ͱ̑ʣ
easy-swooleͷհ
easy-swooleͱ?• https://www.easyswoole.com/• swoole Λ͔ͭͬͨϑϨʔϜϫʔΫ• ेࣄʹ͑ΔʢݸਓͷײͰ͢ʣ• ؆୯γϯϓϧʂ• ݁ߏαΠτཱ͕ɺ͔͠͠େମதࠃޠ
ᐽՍಛੑEasySwoole ੋҰجဋSwoole Server 䇖ؿ֥ӈሁଽթ֥ٳ҃ൔPHPᐽՍɼህູAPIࣕੜɼϥຂԮPHPᄎྛଆൔᄝࣉӱߒఏބ໓ࡱࡆᄛഈջট֥ྟିാbEasySwoole ߴ෧ྃ Swoole Server ࣕґچົӻ Swoole Server ݪ༗ಛੑɼࢧ࣋ಉൈࠁކࡓ๐HTTPɺࣗఆၬTCPɺUDPླྀၰđಞषؿᆀၛቋ֥֮࿐༝ӮЧބࣚ৯щཿԛ؟ࣉӱđॖၳ҄đۚॖႨ֥ႋႨڛༀb
ʢػց༁ͯ͠Έ·͠ΐ͏ʣ
ϑϨʔϜಛੑEasySwooleɺSwoole ServerΛϕʔεʹͨ͠ࢄϝϞϦࢄPHPϑϨʔϜϫʔΫͰɺϓϩηεͷ֮੧ϑΝΠϧಡΈࠐΈʹ͏ύϑΥʔϚϯε্ͷෆརӹΛऔΓআͨ͘Ίʹಛผʹ࡞͞Ε·ͨ͠ɻ·ͩSwoole Server͕ಉ࣌ࠞ߹ϞχλʔHTTPɺΧελϜTCPɺUDPϓϩτίϧɺ։ൃऀϚϧνϓϩηεΛॻ͖ࠐΉͨΊͷ࠷খݶͷίετͱ࿑ྗͰֶशͰ͖ΔΑ͏ʹɺඇಉظతʹɺߴՄ༻ੑΞϓϦέʔγϣϯΛαϙʔτຊདྷͷಛੑΛҡ࣋͠ͳ͕ΒɺEasySwooleͷߴ͞SwooleαʔόʔΛΧϓηϧԽαʔϏεɻ
• ʮͳΔ΄ͲΘ͔ΒΜʯʮͱʹ͔ͦ͘͢͝͏ʯ• ൈਮ͢Δͱ…• Swooleͱ͍͏ͭΛϕʔεʹ͍ͯ͠Δ• SwooleΛ͏·͘ϥοϓ͍͍ͯͯ͘͢͠͠Δ• ࠷খݶͷίετͰֶशɺ࣮͕Ͱ͖ΔΑ͏ʹ
• ݸਓతʹɺSwooleͷίʔϧόοΫࠈΠϕϯτۦಈνοΫͳॻ͖ํΛ͠ͳͯ͘Α͘ͳΔͷ͕࠷ߴ• Web API༻ͳΒ֮͑Δ͜ͱ࣮ࡍ͘͢ͳ͍• ΘΓͱPOPOͳײ͡Ͱɺมͳ͜ͱڧཁ͞Εͳ͍ɺී௨ʹϞμϯͳPHP͕׆͔ͤΔ
swooleͱʁ• https://www.swoole.com/
PHP 䇖ؿದჴॖၛщཿۚྟି֥ၳ҄ѩؿ TCPɺUDPɺUnixSocketɺHTTPɼWebSocket ༀbSwoole ՄҎኅᔟႋႨႿ৳ຩa၍๙ྐaఒြೈࡱaᄉ࠹ෘaຩႳ༤a৳ຩčIOTʣɺӚ৳ຩaᇆିࡅं֩ਵთb ༻ PHP + Swoole ࡞ູຩ๙ྐॿࡏđॖၛఒြ IT ݚؿི֥ؒੱննิശđ۷ࡆህᇿႿषؿԷྍӁb
Swooleɿຊ൪ڥ༻PHPඇಉظωοτϫʔΫ௨৴ΤϯδϯPHP։ൃऀɺߴੑೳͳඇಉظͷTCPɺUDPɺUnix SocketɺHTTPɺ͓ΑͼWebSocketͷಉ࣌αʔϏεΛ࡞Ͱ͖·͢ɻεΥʔϧɺΠϯλʔωοτɺϞόΠϧ௨৴ɺΤϯλʔϓϥΠζιϑτΣΞɺΫϥυίϯϐϡʔςΟϯάɺΦϯϥΠϯήʔϜɺΠϯλʔωοτʢIOTʣɺΧʔωοτϫʔΩϯάɺεϚʔτϗʔϜͳͲͷͰ͘༻Ͱ͖·͢ɻωοτϫʔΫ௨৴ϑϨʔϜϫʔΫͱͯ͠PHP +SwooleΛ༻͢Δ͜ͱͰɺاۀͷITݚڀ։ൃνʔϜͷޮΛେ෯ʹߴΊɺֵ৽తͳͷ։ൃʹͬͱूத͢Δ͜ͱ͕Ͱ͖·͢ɻ
• ͓ΑͦPHPΒ͘͠ͳ͍ػೳ͕ՃͰ͖ΔC֦ு• ࠷ۙݸਓతʹ͖• ࠓճʮΠϕϯτۦಈͰߴͳΞϓϦ͕PHPͰ࣮ݱͰ͖Δʯ͕ॏཁ• httpdʹͳΕΔʂʢݸਓతʹॏཁʣ• ʢੋඇௐͯΈ͍ͯͩ͘͞ɺӳޠαΠτ͋ΔΑʂʣ
• ·ͱΊΔͱɺ• swooleͰಈ͘ϑϨʔϜϫʔΫͷҰ͕ͭeasy swoole• ʢphpͰಈ͘ϑϨʔϜϫʔΫͷslimɺΈ͍ͨͳଊ͑ํͰྑ͍Ͱ͢ʣ
ͰΛͲͯ͠ɺeasy swooleͷ͠Λ͠·͢
easy-swoole ͷ֓ཁ• ϓϩηεɾϫʔΧʔϚωʔδϟʔ• ؆୯ͳϧʔλʔ• ؆୯ͳδϣϒΩϡʔ• γϯϓϧͳΠϕϯτϑοΫ• ͳͲ͕ೖ͍ͬͯΔ
ೖͬͯͳ͍ͷ• ςϯϓϨʔτΤϯδϯ• ϞσϧʢϞσϧͱʁʁʣ• ηογϣϯ• ͳͲผ్͝༻ҙʢͰ͖ΔͰ͠ΐʁʣ
ॏཁͳϑΝΠϧproject App Root dir!"App App Class# !"HttpController# # $"Index.php ίϯτϩʔϥ!"Config.php ઃఆ!"EasySwooleEvent.php Πϕϯτ!"easyswoole easyswoole ίϚϯυ• ͜ΕΒcomposer create-projectͰੜͰ͖Δ• ॻ͔ͳ͖Ό͍͚ͳ͍ͷ࠷ݶIndex.phpͷΈʢޙड़ʣ
• ͡Ό͋ɺͱΓ͋͑ͣىಈͯ͠Έ͔ͬ
easyswooleσʔϞϯʹͳΔ• ·͋ɺphp-fpmͷΑ͏ͳͷ• easyswoole ίϚϯυʹҾΛ͚ͭͯૢ࡞͢Δ• easyswoole startͱ͔
• ʮΊͬͪΌΧϥϑϧͳதࠃޠ…͚ͩͲ·͋ɺͳΜͱͳ͘Θ͔Δɺ͍͚Δ͍͚Δʂʯ• ͨͱ͑…• --d -> ͚ͭΔͱσʔϞϯԽ• --workerNum-1 -> ϫʔΧʔ• (--workerNum 1 Ͱͳ͍…)• --user-nobody -> nobodyϢʔβʔͰ࣮ߦ• (--user nobodyͰͳ͍…ʣ
ϓϩηεɾϫʔΧʔϚωʔδϟʔ• ຊʹ͏ͳΒɺ͘͢͝ॏཁͳͭ• start,stop,reload,daemonize• ϫʔΧʔௐ• respawn• UIDɺGUIDઃఆ
ʮPHPͳͷʹ͔ͬ͠Γ͠ͱΔʯ• ຊʹʢׂͱʣͪΌΜͱϓϩηεΛϚωʔδ͢Δɻ• ͪΌΜͱىಈ͢Δ͠ɺͪΌΜͱࡴͤΔɻ• γάφϧͰϦϩʔυͱ͔Ͱ͖Δʢָʂʂʣ• gracefull restartͪΌΜͱ͢ΔʢΒ͍͠ɺ͋Μ·Γݫີʹݕূͯ͠ͳ͍ʣ• ʮPHPͰ͜ΜͳʹͪΌΜͱ࡞ͬͯ͋ΔϓϩηεϚωʔδϟɺॳΊͯݟ͔ͨ…ʯ
(ճΓ͕ଞͷ͜ΕܥͷͭΑΓ͔ͬ͠Γ͍ͯ͠Δ͜ͱΛհ͢ΔͨΊʹ࠷ॳʹհ͠·ͨ͠ɻ͕ɺ·͋ɺօ͞ΜPHPͰσʔϞϯ࡞ͬͨΓ͠ͳ͍Ͱ͔͢Ͷ……)
httpdʹͳΕΔʂ• ܁Γฦ͠ʹͳΓ·͕͢ɺhttpdʹͳΕ·͢ɻ• ͳΕΔͱ͍͏Ҏ্ʹಘʹॏཁͳͳ͍ɺͳΕΔͱ͍͏͜ͱ͕ॏཁɻ• fastCGI͏ઃఆͨ͘͠ͳ͍ΆΑ…• nginxͷίϯϑΟά͕…
server {root /path/to/htdocs/;location / {proxy_http_version 1.1;proxy_set_header Connection "keep-alive";proxy_set_header X-Real-IP $remote_addr;if (!-e $request_filename) {proxy_pass http://127.0.0.1:9501;}}}
ָʂʂʂ
தؒ·ͱΊ• easyswooleίϚϯυͰىಈͰ͖Δ• httpd αʔόʔʹͳΕΔ• ʢ͜͜·Ͱ̍̌ʣ
• ࣍ίʔυΛݟ͍͖ͯ·͠ΐ͏• ΣϒΞϓϦࡶʹ͍͑ίϯτϩʔϥʔ͕͋ΕͲ͏ͱͰͳΔʢݴʣ
ίϯτϩʔϥʔ(ϧʔλʔ)• easyswooleʹɺ֓Ͷϧʔλʔ͕2छྨ͋Δ• ඪ४ͷίϯτϩʔϥʔ• ΧελϜϧʔλʔ• ʢ͋Δ͍ΧελϜϧʔλʔࠩ͠ସ͑ʣ
ඪ४ͷίϯτϩʔϥʔ• /{Ϋϥε໊}/{ϝιου໊} Έ͍ͨͳελΠϧͰϚοϓɺઃఆϑΝΠϧແ͍• /Auth/Login -> \App\HttpController\Auth::login()• / -> \App\HttpController\Index::index()• /HelloWorld -> \App\HttpController\HelloWorld::index() or \App\HttpController\Index::HelloWorld()
• RESTͮ͠Β͍• HTTP MethodΓ͚ແ͍ɺURLύϥϝλύʔε͠ͳ͍• ʮผʹRESTͳͯ͘ࢮͳͳ͍͠…ʯʮࢮ͵ਓ͍Δʯ• ͦ͏͍͏ਓ͏ҰͭͷΧελϜϧʔλΛ͔͓ͭ͏• γϯϓϧͩ͠ɺઃఆ͍Βͳ͍͠ɺURL͕៉ྷͰͳ͍͍ͯ͘͠…ͱ͍͏͜ͱͰݸਓతʹͪ͜Β͕…• ʢGET ?id=1͘Β͍ͳΒڐͤΔ͠ɺෳࡶͳύϥϝλJSONΛPOST͢Ε͍͍ͱࢥ͍ͬͯΔݹ͍ਓؒͷൃͰ͢ʣ
ʢඪ४ͰͷʣσΟεύον͞ΕΔΫϥεͷߏ• ʢϧʔλʔ͔ΒσΟεύον͞ΕΔίϯτϩʔϥ͜ͱΞΫγϣϯ…ʣ• EasySwoole\Core\Http\AbstractInterface\ControllerΛΠϯϓϦ͢Δ• PSR-7ޓͷrequest/response͕ϓϩύςΟܦ༝Ͱ͑Δɻ
namespace App\HttpController;use EasySwoole\Core\Http\AbstractInterface\Controller;class Hello extends Controller{function index(){$this->response()->write('Hello easySwoole!');}}
ʮPSR-7͠Βͳ͍ਓʹૣΘ͔Γʂʯ• echoͱ͔͠ͳ͍(ͯ͠ϒϥβʹ͍͔ͣɺίϯιʔϧʹग़Δ)• $this->response()->write('Hello easySwoole!');ͱ͔͢Δ• $_POST['name']ͱ͔͠ͳ͍• $this->request()->getParsedBody()['name'];ͱ͔͢Δ• (རผ్άάͬͯ͘Ε)
͍͔ͭ͘ͷಛผͳϝιου͕͋Γ·͢• actionNotFound() -> 404ͷͨΊ• onException() -> ΤϥʔϋϯυϦϯάͷͨΊ• ʢ͜ͷ͋ͨΓ __hook()ͷ࣮ΛΈΔͱཧղͰ͖·͢ʣ
ΞΫγϣϯͷલͱޙͷॲཧࠩ͠ࠐΈ• onRequest()• ϦΫΤετલʹॲཧ• ϨεϙϯεΛฦͯ͠͠·͏ࣄͰ͖ΔʢೝՄͳͲʣ• afterAction()• Action͕ਖ਼ৗʹऴ͑ͨΒॲཧ• ͲͪΒ࣍ʹΛ͚ͨ͠Εɺ$this͕͑·͢
͏Ұͭͷख๏ɺΧελϜϧʔλʔ• nikic/FastRoute ͦͷͷɻͳͷͰলུ• https://www.easyswoole.com/Manual/2.x/En/_book/Http/router.html• ΞΫγϣϯͷ࡞Γඪ४ͷίϯτϩʔϥʔͱ͜ͱͳΓɺҾʹreq/resΛ͍ΕΔPSR-7ରԠFWʹΑ͋͘ΔܗʹͳΓ·͢$routeCollector->get( '/user/{id:\d+}',function (Request $request ,Response $response,$id){$response->write("this is router user ,your id is {$id}");$response->end();});
ίϯτϩʔϥ·ͱΊ• ݟͯͷ௨Γɺී௨ͷʢPSR-7ରԠFWͷʣPHPͱେࠩͳ͍
• ͪΐͬͱҧ͏ͷ͕࣍ͷΠϕϯτपΓ͔Β
ΠϕϯτϑοΫ• SwooleʹαʔϏεʢεϨουʢεϨουͰͳ͍ʣͷΑ͏ͳͷʣΛՃͰ͖Δ• ΣϒΞϓϦʢίϯτϩʔϥͳͲʣΑΓ্Ґʹଘࡏ
frameInitialize()• easyswooleϑϨʔϜϫʔΫىಈ࣌ʹ࣮ߦ• swooleΛ࣮ߦ͢Δલ• ઃఆಡΈࠐΈ֤छΩϟογϡύʔδͳͲ
mainServerCreate()• ϝΠϯαʔόʔʢϚελʔϓϩηεʣ࡞தɺswooleΤϯδϯ࣮ߦલ• httpdҎ֎ʹಉ࣌ʹಈ͔͢αʔϏεొͱ͔• λΠϚʔCronͱ͔• Ұ෦յΕʹ͍͘γϯάϧτϯॳظԽͱ͔• DBͷଓPoolॳظԽͱ͔• Ωϟογϡ༻Redisͷଓͱ͔
onRequest()• ΞΫγϣϯͷͦΕͱࣅ͍ͯΔͷͰলུ
afterAction()• ΞΫγϣϯͷͦΕͱࣅ͍ͯΔͷͰলུ
• ʮΠϕϯτɺԿʹ͔ͭ͏ͷʁʯ• ʮ͍͍ɺ͜ͷ͋ͨΓ͕ݸਓతʹΞπ͍ͱ͜ΖͰʂʯ
γϯάϧτϯͩʂʂʂ• PHPer͕ਆʹېࢭ͞ΕͨېஅͷՌ࣮• ʮϦΫΤετΛ·͍ͨͰʯଘଓͤ͞ΒΕΔ͞·͟·• mainServerCreateframeInitializeͰ࡞Δͱɺࢠ͑Δ• classؔͷstaticͰ࡞ΔͷมΘΒͣ• ʢҰԠDI(DIͱʁ)͋ΔΑʣ
• ҙਂ͘͏ͱ࠷ߴʹؾ͕͍͍ʢؾͳͷʁʣ• (PHPेʹૣ͍ͷͰɺ࣮ۜͷؙͰͳ͍)• ҆શʹγϯάϧτϯʹ͢Δͷɺ͘͢͝ɺ͍͠• ྫɿΫΤϦ࣮ߦॱং͕༧֎ʹͳΔɺϑΝΠϧग़ྗ่͕ΕΔɺผͳॴͰΤϥʔͰյΕΔ• ීஈΤϥʔϋϯυϦϯάΛࡶʹߦ͍ͬͯΔਓࢮ͵• ঢ়ଶΛ࣋ͨͳ͍ɺϓϦΩϟογϡͳͲॳظԽ͕ॏ͍͚ͩͱ͔ͳΒൺֱత҆શ
• prefork+eventͷΈͳͷͰɺ࡞ΔॴʹΑͬͯάϩʔόϧʹͳΒͳ͍• ͳͷͰɺmainServerCreateframeInitializeͰ࡞ΔͳͲ͢Δ• ϦʔΫ͕ා͍ͷͰɺेʹmax_requestΛͷͯ͠ɺࢠʢϫʔΧʔʣͰੜͨ͠΄͏͕҆શ…ɻ• ઃఆճॲཧ͢ΔͱϫʔΧʔ࠶ىಈ͢Δ• ·͋ɺ࣮ߦසΛ1/10000ʹͳΕे
λΠϚʔͩʂʂʂ• ී௨ͷPHPͰ͍ͩͿ໘ͳࣄͷҰͭ• ʮΩϟογϡΛ10ඵʹ1ߋ৽͢ΔʯʮϋʔτϏʔτΛૹ৴͢ΔʯΈ͍ͨͳ͕ͭ؆୯҆શʹͰ͖Δ• mainServerCreateʹɺλΠϚͷαʔϏεΛొ͢Δͱಠཱͯ͠ಈ͍ͯ͘ΕΔ
public static function mainServerCreate(/* ... */): void{// timerͰ1ඵຖʹΠϯλʔόϧ࣮ߦ$register->add($register::onWorkerStart, function ($server, $workerId) {if ($workerId == 0) {Timer::loop(1000, function () {echo 'TICK!';});}});}
ඇಉظϦΫΤετʢΠϕϯτۦಈʣ• Πϕϯτۦಈͱ͍͑͜Εʢཁग़యʣ• ྫɿ֎෦APIʹϦΫΤετͯ݁͠ՌΛදࣔ͢Δ• ྫ̎ɿυϝΠϯΛνΣοΫ͍͕ͨ͠DNS͍߹Θ͍ͤ• ී௨ͷphpͰ݁Ռऔಘ·Ͱී௨ʹϒϩοΩϯάʢϓϩηεઐ༗ʣͯ͠͠·͏• ΠϕϯτۦಈͰ࡞Εϓϩηεઐ༗͠ͳ͍• easyswooleෳϓϩηεಈ࡞Ͱ͖Δ͔Βଈഁ໓తʹͳΒ
• ʮϝΞυݕূͰDNS͍߹Θ͍ͤͨ͠ʯ• ඇಉظͰਖ਼Ҿ͖͢Δʹswooleͷco::gethostbyname͕͋Δ• ίϧʔνϯͰͭ͘ΒΕͨͷ• ແବͳ࣌ؒΛɺϦΫΤετؒͰ༥௨• co::gethostbynameύϥϨϧऔಘͰͳ͍ͷͰʮͦͷϦΫΤετ͘ͳΒͳ͍ʯ• ͦͷ͔ΘΓɺଞͷϓϩηεͷअຐΛ͠ͳ͘ͳΔ
• ʮίϧʔνϯͬͯͳʹʁʯ• ʮίʔϧόοΫແؒࠈΛ͖ͬ͢Γͤ͞ΔͨΊͷͷʯ• ίϧʔνϯ͚ͩͰΓͳ͍ͱ͖ํͳ͘ΠϕϯτۦಈͰॻ͘ࣄͳ͍Θ͚Ͱͳ͍…• ͨͩɺswoole֤ॴͷίϧʔνϯԽΛઈࢍਪਐதʢΒ͍͠ʣ
ϕϯνͰ࣮ଌ• ϗετ໊ΛҾ͖·͘ΔURLʹෛՙΛ͔͚Δʢlookup(Normal|Co))• ͦͷ࣌ʹɺผͷΞΫγϣϯʹෛՙΛ͔͚ͯΈΔʢhelloΞΫγϣϯʣ• helloΞΫγϣϯΛlookup͕अຐ͠ͳ͍͔ʁͱ͍͏ςετ• Θ͔Γ͘͢͢ΔͨΊɺϫʔΧʔ:1ɺಉ࣌ଓ:32
function lookupCo() {// ίϧʔνϯ൛for($i=0; $i<100; $i++) {$ip = \Swoole\Coroutine::gethostbyname("dns.google.com");}}function lookupNormal() {//ී௨൛for($i=0; $i<100; $i++) {$ip = gethostbyname("dns.google.com");}}function hello() { $this->response()->write('hello'); }
• lookupNormalͷํʹෛՙΛ͔͚ͭͭɺhelloʹෛՙΛ͔͚Δࢼݧ• lookupNormal: 1.65 rps• hello: 1.69 rps• lookup͕ϒϩοΫͯ͠ɺhello͕΄΅ಉ͡ʹ
• lookupCoʹෛՙΛ͔͚ͭͭɺhelloʹෛՙΛ͔͚Δࢼݧ• lookupCo: 1.64 rps // ͜͜େ͖͘มΘΒͳ͍• hello: 147.36 rps // 100ഒʹ• lookup͕͍߹ΘͤதʹଞͷॲཧΛਐΊΔͷͰϒϩοΫͮ͠Β͘ɺhello͕͘ͳͬͨ
• ΠϕϯτۦಈʹϒϩοΩϯάॲཧఢ• ϚϧνϓϩηεͳΒɺ͜ͷ੍ݶଟগ؇͞ΕΔ• ʮϒϩοΫ͢Δಉ࣌ଓʻϫʔΧʔʯ ͳΒ͍• Swooleͦͷػೳ͕ͪΌΜͱἧͬͯΔɺ࠷ߴʂ• ʢͱ͍͑ɺ҆қʹϫʔΧʔ૿͢ͷඍົʣ
• ղܾʂͱ͍͍͍ͨͷ͕ͩ…ɻ
͜͜Ͱ࣮༻্ͷ• swooleʹίϧʔνϯͷco::gethostbyname͕͋Δͷ͕ͩ…• λΠϓΛࢦఆͰ͖ͳ͍…• https://wiki.swoole.com/wiki/page/790.html• ϝʔϧϑΥʔϜҊ݅ͰɺMXҾ͚ͳ͍ͱ͜·Δ• ʮ͡Ό͋DNS protoΛswooleͰ࣮͠Α͏ʂʯ…ͱͳΒͳ͍ʢͰ͖Δ͕ɺ໘͗͘͢͞Δʣ
• HTTPSͰDNSͻ͚͍͍ΑͶɺͱ͍͏͜ͱͰ• DNS-over-HTTPS• https://developers.google.com/speed/public-dns/docs/dns-over-https• swoole ʹ Coroutineͷhttp client͕͋Δ
protected function isProbablyExistsMailServer($host){$goog_dns = "dns.google.com";$dns_ip = static::getHostByNameWithCache($goog_dns);$cli = new \Swoole\Coroutine\Http\Client($dns_ip, 443, true);$cli->setHeaders(['Host' => $goog_dns,"User-Agent" => 'php','Accept' => 'application/json','Accept-Encoding' => 'gzip',]);$encoded_host = urlencode($host);
$cli->get("/resolve?name={$encoded_host}&type=MX");$mx_records = json_decode($cli->body, true);$cli->get("/resolve?name={$encoded_host}&type=A");$a_records = json_decode($cli->body, true);$cli->close();return isset($mx_records['Answer']) || isset($a_records['Answer']);}function some(){$res = $this->isProbablyExistsMailServer('example.jp')? "found":"notfound";}
• ͱ͍͏͜ͱͰɺແࣄAϨίʔυͱMXϨίʔυΛҾ͚ΔΑ͏ʹɺ• ͪΖΜεοΩϦCoroutineͰͶʂ
தؒ·ͱΊ• ϝΠϯϓϩηεͷଘࡏʢΠϕϯτʣ• ΠϕϯτۦಈΛ·ͤΔϒϩοΩϯάॲཧΛ؆ศʹճආͰ͖Δ͋Ε͜Ε• ͦͯ͠ΠϕϯτʹϓϩάϥϜΛొͯ͠αʔϏεԽ
• (લͷਤ֓೦ਤͰ͢ɺϝΠϯϓϩηε͋ͨΓͷߏ͕ຊͱҧ͏ͣ)• ݸਓతʹ৭ʑΞπ͍͠ɺօ͞Μʹઆ໌Λ্͍͕ࠩ͛ͨ͠ɺ͕࣌ؒͳ͍ͷͰলུ
• ͦͷଞʹeasy swooleʹศརػೳ͋Γ·͢ɻ
λεΫ• easy swooleʹΈࠐΈͰδϣϒϫʔΧʔ͕͋Δ• ΫϩʔδϟΛ࡞ͬͯTaskManager::async()ʹೖΕΔ͚ͩͳͷͰָ• ΛΫϩʔδϟʹuseͰ͚ͭͯૹΕ·͢• ผ్δϣϒϫʔΧʔ͕͍Βͳ͍ͷͰ؆୯ศརʂʂ
λεΫͷొclass Index extends Controller{function index() // ͱ͋Δίϯτϩʔϥʔ{ // ...$this->response()->write('Ϩεϙϯε');$some = 'data';TaskManager::async(function () use ($some) {$log = new Log;$log->set($some); // ॏ͍ॲཧͳͲ}); // ผʹλεΫొ࠷ޙͰͳͯ͘Α͍}}
• TaskManager::async()δϣϒొ͔͠͠ͳ͍ͷͰ• ʢλεΫͱͳΔΫϩʔδϟΛγϦΞϥΠζͯ͠อଘͨ͠Βʣ• ࣍ͷߦ͢͢Ή• ʢͭ·ΓɺϦΫΤετ͕ऴΘΔʣ
λεΫͷॲཧ• ޙͰtaskΛϫʔΧʔϓϩηε͕र࣮ͬͯߦ• ಛʹઃఆແ͍ʂ؆୯ͩʂ• ʮ͑ͬɺผϓϩηεʹΫϩʔδϟΛ͛Δͷʁʯʮ͍ʯ• SuperClosureͰγϦΞϥΠζ͍ͯ͛ͯ͠Δ• ʢͳͷͰɺෳࡶͳσʔλʢFDΛͬͯΔͱ͔ʣΛΫϩʔδϟʹ͍ΕΔͱͩΊͰ͢ʣ
easySwoole\Cache• ʮ͍߹Θͤ͢ΔͳΒΩϟογϡඞਢͰ͠ΐʯʮͤͳʯ• easyswooleͰ͑Δ؆୯ͳKVS• ϩʔΧϧFSɺredisɺmemcachedͳͲΞμϓλ• ʢʮੌ͘ྑ͍ͷʯͰͳ͍ɺಛʹswooleಠಛͷػೳ͔ͭͬͯͳ͍͠ʣ• ·͋ɺ؆୯ศརͳͷͰɻ
public static function frameInitialize(): void{// ॳظԽCache::init(new Files(['expire' => 0, // ߏթݖ௹ൈࡗ'cache_subdir' => true, // 䇖ఓሰଢթ٢'prefix' => '', // ߏթ໓ࡱުሗ'path' => __DIR__.'/cache', // อଘDIR'hash_type' => 'md5', // จ໊݅తᄒرํࣜ'data_compress' => false, // ఓႨߏթଽಸ෪'thread_safe' => false, // ϑΝΠϧϩοΫ͢Δ͔'lock_timeout' => 3000, // จ݅࠷Ӊ෭קൈࡗ(ms)]));
Cache::get('name', 'औಘͰ͖ͳ͔ͬͨΒ');Cache::set('name', 1, $ttl);Cache::has('name');Cache::delete('name');Cache::clear();Cache::set('name', 1);Cache::inc('name');// +1Cache::dec('name', 10);// -10Cache::pull('name', 'औಘͰ͖ͳ͔ͬͨΒ');// popCache::remember('name', 'value'); // ͳ͚Εset
protected function getHostByNameWithCache($host){$val = Cache::get($host, null);if(!is_null($val)){ return $val; }$ip = \Swoole\Coroutine::gethostbyname("dns.google.com");Cache::set($host, $ip, 3600);return $ip}
தؒ·ͱΊ• TaskͰॏ͍ॲཧશ෦ޙΖʹ͛ͯɺϨεϙϯεΛฦͤΔ• લड़ͷඇಉظϦΫΤετΛ͔ͭ͏ʹͯͬ͠ͺΓΩϟογϡ͍͔ͨ͠ΒCacheศར• easyswooleʹTaskCacheͳͲɺ΄΅ઃఆͳ͘γϯϓϧʹύοͱ͔ͭ͑Δػೳ͕͋ͬͯศར
easy-swooleհ·ͱΊ• ϝʔϧϑΥʔϜΛߴԽ͢Δʹ͋ͨͬͯ• ϑΥʔϜΛදࣔ -> ूܭσʔλΛද͓ࣔͯ͘͠• ֬ೝը໘ -> ϝΞυଘࡏ֬ೝͷDNS͍߹ΘͤඇಉظͰ• อଘ -> λεΫԽͯ͠ͱʹ͔͘ฦ͢• ͱ͍ͬͨࣄ͕easy swooleͰϥΫϥΫͰ͖Δ
• ී௨ͷPHPͰॻ͘ͱɺΕผϓϩηεʹδϣϒΩϡʔͩɺΕredisͩɺͳͲͱෳࡶԽ͕ͪ͠ɻ• ϑϧελοΫFWͳΒେମೖͬͯΔ͚Ͳɺ͍࣌͠ʹyak shaving͕ḿΔࣄଶ͠͠• ʢ·͋ɺԿͰॳΊͯ͏࣌৭ʑמΔඞཁ͋ΔͰ͠ΐ͏͕…ʣ• ͦͦ୯ͳΔςϯϙϥϦͳԠืϑΥʔϜʹͰ͔͍ϑϨʔϜϫʔΫ͍ͨ͘ͳ͍
• ͦ͜Ͱɺeasy swooleͳΒɺΑ͋͘Δʮ͋Ε͕΄͍͠ʂʯʹγϯϓϧͳͨ͑ͯ͘͜ΕΔͧʂ• ʢΠϕϯτۦಈʹ׳Ε͍ͯͳ͍ਓͰɺeasyswooleγϯϓϧͩͱࢥ͏…ଟʣ• swoole·ͰؚΊͯɺ͞Βʹ৭ʑػೳ͕͋Δͧʂࠓճհ͠ͳ͔͚ͬͨͲɺDBͷଓpoolͱ͔͋Δͧʂ• ͱ͍͏͜ͱͰswooleͪΐͬͱ…ͱ͓͍ͬͯͨօ͞Μɺͥͻeasy swooleͰপʹೖͬͯΈ·͠ΐ͏ʂ
͜͜·Ͱ͘ΕͱΓ͋͑ͣޭʢʁʣ
͔͜͜Β༨ஊ• ͋Δ͍ຊฤ• ʢ͜͜·Ͱ̍̑Ͱ͍͖͍ͨʣ
Swoole͕དྷ͍ͯΔ݅• օ͞Μ৴ٙɺ͋Δ͍ྵ৴શٙͰ͠ΐ͏͕• Composer ύοέʔδొࢹϘοτ(@call_user_func)ͷۙπΠʔτΛgrepͯ͠ΈΔͱ…
$ cat bot_log |grep swoole| wc -l25$ cat bot_log |grep laravel| wc -l333$ cat bot_log |grep slim| wc -l15$ cat bot_log |grep cakephp| wc -l22$ cat bot_log |grep zend| wc -l8
͍͢͝ɺظؒʹ্͕͍̎̑ͬͯΔʂʂ• ʢظؒͱʁʁʁʣ• CakeSlim,Laravelͱͷ૬ରײΛָ͓͠Έ͍ͩ͘͞ɻ
GitHubͰεΰΠଟ͍
packagist ଟ͍
• (ݟͮΒ͍…ʣ• 1ϖʔδ20͕݅18p͋ͬͨͷͰɺ350ݸ͘Β͍͋Δͣ
awesome-swoole ૿͑ͨʢʁʣ• https://github.com/swooletw/awesome-swoole• https://github.com/yannsun/awesome-swoole• https://github.com/swoole/swoole-src/wiki/Awesome• ʢଟ͚Εྑ͍ͱ͍͏ͷͰͳ͍͕ʣ
• laravelͱ͔ɺ֤छwafͷόΠϯσΟϯάʢྫʣ૿͑ͨ• Ͱ·͋ɺϑϧελοΫͷFWΛSwooleͰಈ͔͢ҙຯ…ɻ• Promiseͱ͔mqttͱ͔ftpserverʢʁʁʁʣͱ͔࣮༻తͳपลϥΠϒϥϦ
࣍ͷόʔδϣϯ̐ʂ
• ͳΜͰ͕̏εΩοϓ͞ΕΔͷ͔Θ͔ΒΜ• ੈͷதʹṖ͕ଟ͍ɻ
ϑϨʔϜϫʔΫग़࢝Ί͍ͯΔ
ͱ͍͏͜ͱͰ• ࠓճʮָʯͳͷͰeasyswooleΛհ͕ͨ͠ɺຊʹ༷ʑͳϥΠϒϥϦ͕Ͱ͍ͯΔ• ͨΓͳ͍ͷຊਓ͕ಡΈ͍͢ใνϡʔτϦΞϧ͚ͩͰʁʢʁʁʣ• swooleͷϏοάΣʔϒʹΔ͔͠ແ͍ʢݹ͍ʣ• ʢࣗҎ֎ʹͬͯΔਓΈͨ͜ͱ͕ͳ͍ͷ͕Έʣ
• Tencentɺͬ͞͞ͱʢུʣͱ͔ผͷݴޠʹ͍͔ͣɺҊ֎ͪΌΜͱ͚͍͍ͭͮͯͯ͢͝ɻ• PHPݴޠʹϋϚ͍ͬͯΔʢʣձࣾࠜੑͰPHPΛ೧͡ۂ͛Δ͔Β͍͢͝ɻ
͍
Πϕϯτۦಈͱͦͷଞʹ͍ͭͯൺֱ• Πϕϯτۦಈͬͯ৭ʑ͋Δ• swooleΠϕϯτʴϓϩηε• reactPHPΠϕϯτ• fpmmod_phpϓϩηεʢpreforkʣ• cgiϓϩηε
• શ෦͕ผΕ͍ͯΔ• ͦΕͧΕ࣮ߦ͍ͯ͠ΔPHPίʔυ͕ҟͳͬͯΑ͍• phpࣗମprefork͞ΕΔ͕ɺຖճϓϩάϥϜىಈ͍ͯ͠Δ• ͳͷͰɺCGIɺmod_phpͱΜͳ͕ࠩগͳ͍
• యܕతͳΠϕϯτۦಈ• ࣮ߦ͞ΕΔPHPίʔυ͔̍ͭ͠ͳ͍• ྫ reactPHPͳͲ• ϝΠϯϧʔϓ͕ҰͭͳͷͰɺϝΠϯϧʔϓͰͳʹ͔٧·Δॲཧ͕͋Εશ෦ࢭ·Δ• ຊʹϊϯϒϩοΩϯάʹॻ͚ΕޮతʹΈ͑Δ͕ɺίΞ͕׆͔ͮ͠Β͍
• ΠϕϯτͱϓϩηεΛ͋Θͤͨͷɺswoole͜ΕɻreactPHPΛϚϧνϓϩηεʹ͢Δͷ͋Δ• ʢجຊతʹʣࣄલʹPHPίʔυΛ࣮ߦ͠ίʔϧόοΫʢϝΠϯϧʔϓʣΛ࡞ΔͷͰɺPHPίʔυҰͭ• ϝΠϯϓϩηε͕ड͚ͯࢠʹΘ࣮͕͍ͨ͢͜͠• ଟগϒϩοΩϯά͕͋ͬͯɺଞͷϓϩηε͕͕ΜΕΔ༨͕Δ• ཧ্ɺreload͕Ͱ͖Δ• ເ͕͋Δʂʢʁʣ
ʮ…͍Μ͚ͩͲʁʯ• ·ͣɺଟॏԽͰ͖ͳ͖ΌͦΕͳΓͰ͢• 100rpsҎ্͕ඞཁͳ͍ͳΒɺޡ͔ࠩͳ…• MacͰಈ͕͘ɺ͍͍ͬ͢͝• ϕϯν͢ΔͳΒLinuxͰɻ• ʢಉ͡MacͷVM্Ͱ͏͔ͯ͝͠ɺ5ʙ50ഒ͍ʣ
Πϯετʔϧํ๏ʁ• swooleී௨ͷ֦ுͱಉ͡$ git clone https://github.com/swoole/swoole-src.git$ cd swoole-src/$ phpize$ ./configure --enable-openssl$ make all$ make install$ echo "extension=swoole" >> /etc/php/7.2/cli/conf.d/30-swoole.ini
• ґଘ͕ͳ͍ͷͰɺ͢ΜͳΓ͍Δͱࢥ͍·͢• peclͰೖΕΒΕΔΒ͍͠ʢ࠷৽όʔδϣϯΛ͔Μ͕͑Δͱɺgit͕Α͍͔ͱ)• easy-swoolecreate-project͕͍$ composer create-project easyswoole/app easyswoole
swooleͷόʔδϣϯʹ͍ͭͯ• 2ܥʹͳ͍ͬͯͩͿͨͬͯɺͦΕͳΓʹ҆ఆ͖ͯ͠·ͨ͠ɻ• ͕ɺεςʔϒϧͱ͍͏֓೦͋Μ·Γͳ͍ؾ͕͠·͢ɻ• มͳڍಈ͕͋ͬͨΒɺόʔδϣϯΛ͛ͯ͞Έ͍ͯͩ͘͞• ৽نػೳେମόάͬͯ·͢ɺಛʹOSXͰɺ͝ҙɻ
։ൃαϙʔτ• 䎔ဋIDEॿख(ิ༻ϔϧύ)• composer require easyswoole/swoole-ide-helper• https://www.easyswoole.com/Manual/2.x/Cn/_book/Introduction/install.html• (SwooleC֦ுͳͷͰɺϔϧύΛ͍Εͳ͍ͱิͰ͖ͳ͍Օॴʣ• ʢrequire-devͰeasy-swooleΛ͍ΕͨΒೖΔʣ
• ಣࡆᄛ(Hotreload)• ػೳͱͯ͋͠ΔΘ͚Ͱͳ͍͕ɺfswatchΛ͔ͭͬͨྫΛهࡌ• https://www.easyswoole.com/Manual/2.x/Cn/_book/Introduction/server.html
systemd• ී௨ʹॻ͚ී௨ʹಈ͘• systemdͰىಈ͢ΔͱɺϩάLogsͰͳ͘journalctlͰݟΔ͜ͱʹͳΔ• ʢ࣍εϥΠυʹઃఆαϯϓϧʣ
[Unit]Description=swoole serviceAfter=network.target[Service]Type=simpleLimitNOFILE=65535WorkingDirectory=/path/to/easyswoole-sample/ExecStart=/usr/bin/php /path/to/easyswoole-sample/easyswoole start --pid-/path/to/easyswoole-sample/Log/pid.pidExecReload=/bin/sh -c "/bin/kill -USR1 `cat /path/to/easyswoole-sample/Log/pid.pid`"ExecStop=/usr/bin/php /path/to/easyswoole-sample/easyswoole stop --pid-/path/to/easyswoole-sample/Log/pid.pidRestart=alwaysUser=www-data[Install]WantedBy=multi-user.target
reloadपΓʹ͍ͭͯ• ϝΠϯϓϩηεʹSIGUSR1ΛૹΔͱϦϩʔυ• opcacheΫϦΞ͞ΕΔ• easyswooleͷreloadͳΜ͔͓͔͍͠ࣄ͕͋ΔͷͰɺʮࢲʯϝΠϯϓϩηεʹγάφϧΛૹ͍ͬͯΔ• ͠ࢠϓϩηεͷPID͕มΘΒͳ͚Ε(respawnͯ͠ͳ͚Ε)͓͔͍͠• ʮίʔυΛಡ͏ʯ
هɿࣗલͰcacheΛੜ͢ΔϥΠϒϥϦʹҙ• Πϕϯτۦಈ͕લఏͰॻ͔Ε͍ͯͳ͍ίʔυଟ͍• reloadͯ͠ө͞Εͳ͍ʂ• ϑΝΠϧʹॻ͖ग़ͭ͢ແͦͷΩϟογϡফͯ͠reload͢Δ͜ͱ• respawn·Ͱͷִ͕͍ؒͳΒɺcache͠ͳͯ͘Α͍ͷͰʁ
nginx ͱͷ࿈ܞ• nginxͱswooleΛಉډͤ͞ΔͳΒunix socket͕Φεεϝ• ͨͩɺߴෛՙαʔϏεͳΒswooleͱnginxΛN:1ʹ͢Δ͜ͱ͋ΔͩΖ͏• ͜͏͍͏࣌ɺhttpdʹͳΔͷָͰ͍͍Ͱ͢Ͷʂ• ʢ࣍εϥΠυʹઃఆαϯϓϧʣ
server {listen 80;root /path/to/htdocs;server_name _;location / {proxy_http_version 1.1;proxy_set_header Connection "keep-alive";proxy_set_header X-Real-IP $remote_addr;# proxy_pass http://127.0.0.1:9501;proxy_pass http://unix:/tmp/swoole.sock:;}}
unix socket ࣌ͷConfig.php• HOSTʹύεΛࢦఆ͢Δ• PORTແࢹ͞ΕΔ• sockϑΝΠϧͷPermissionࢦఆෆՄɺnginxͱҧ͏UIDͰಈ͔͢ͳΒsockϑΝΠϧΛchmod͢ΔͱΑ͍(swooleͷαϯϓϧίʔυͰͦ͏ͳ͍ͬͯͨ)• Bad gatewayͰɺchmod 777 /tmp/swoole.sock࣏ͯ͠Ε͜ΕɺϩάΈΕΘ͔Δɻ
return [// ...'MAIN_SERVER'=>['HOST'=>'/tmp/swoole.sock','PORT'=>0,'SERVER_TYPE'=>\EasySwoole\Core\Swoole\ServerManager::TYPE_WEB_SERVER,'SOCK_TYPE'=>SWOOLE_UNIX_STREAM,// ...
EOL