Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
最近メールフォームかいてないメールフォーマーによる、ちょっとだけ変わった一応PHPのメールフォ...
Search
uzulla
June 15, 2018
Programming
4
7.8k
最近メールフォームかいてないメールフォーマーによる、ちょっとだけ変わった一応PHPのメールフォーム(?)のお話 〜副題 最近swooleがたのしいです〜
at 全然野菜(PHPCon Fukuoka 2018 非公式 前々夜祭)
20min talk
https://pepabo.connpass.com/event/85144/
uzulla
June 15, 2018
Tweet
Share
More Decks by uzulla
See All by uzulla
ALL CODE BASE ARE BELONG TO STUDY
uzulla
30
7.2k
バイブスあるコーディングで ~PHP~ 便利ツールをつくるプラクティス
uzulla
1
480
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
1.8k
似たもの同士のPerlとPHP
uzulla
1
270
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
190
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
290
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
220
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
2.8k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
6
1.3k
Other Decks in Programming
See All in Programming
AIコーディングエージェント(NotebookLM)
kondai24
0
160
愛される翻訳の秘訣
kishikawakatsumi
1
300
関数の挙動書き換える
takatofukui
4
780
안드로이드 9년차 개발자, 프론트엔드 주니어로 커리어 리셋하기
maryang
1
110
STYLE
koic
0
120
20 years of Symfony, what's next?
fabpot
2
340
Why Kotlin? 電子カルテを Kotlin で開発する理由 / Why Kotlin? at Henry
agatan
2
6.9k
大体よく分かるscala.collection.immutable.HashMap ~ Compressed Hash-Array Mapped Prefix-tree (CHAMP) ~
matsu_chara
1
210
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
140
ViewファーストなRailsアプリ開発のたのしさ
sugiwe
0
430
堅牢なフロントエンドテスト基盤を構築するために行った取り組み
shogo4131
8
2.2k
LLMで複雑な検索条件アセットから脱却する!! 生成的検索インタフェースの設計論
po3rin
2
630
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
56
14k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.8k
Building an army of robots
kneath
306
46k
How STYLIGHT went responsive
nonsquared
100
5.9k
Optimizing for Happiness
mojombo
379
70k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Scaling GitHub
holman
464
140k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
A Modern Web Designer's Workflow
chriscoyier
698
190k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
Context Engineering - Making Every Token Count
addyosmani
9
490
Transcript
࠷ۙϝʔϧϑΥʔϜ͔͍ͯͳ͍ϝʔϧ ϑΥʔϚʔʹΑΔɺͪΐͬͱ͚ͩม ΘͬͨҰԠPHPͷϝʔϧϑΥʔϜ ʢʁʣͷ͓ ෭ ࠷ۙswoole͕ͨͷ͍͠Ͱ͢
• uzulla • ౦ژീԦࢠ͔Β͖·ͨ͠ • ࠷ۙؾʹͳΔͷnginx unit
• ୈҰষ ࣄྫͱ͔ϕϯνͱ͔ • ୈೋষ easy-swooleͷհ • େࡾএ
ࣄྫͱ͔ϕϯνͱ͔
͋Δͷࣄྫ • ಥવͷMOSUCON
MO-ney ga SUCO-shi sika N-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൛ͱɺී௨ʹಈ͘൛ಉࠝ
None
• ʮԠื૯ʯԠืΛ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 connections Thread Stats Avg Stdev Max +/- Stdev Latency 5.13s 2.83s 9.95s 58.97% Req/Sec -nan -nan 0.00 0.00% 4022 requests in 10.00s, 2.14MB read Requests/sec: 402.19 Transfer/sec: 218.75KB
N php-fpm swoole 1 402 2530 50 946 5782 100
931 5429 150 Τϥʔ 5335 200 - 5994 500 - 6612 1000 - Τϥʔ
None
ϕϯν̎ • /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 swoole 1 110 303 10 412 477 100
408 514 150 Τϥʔ 537 200 520 400 540
None
• 500Ҏ্ɺab͕ΤϥʔΛు͍ͨͷͰ…
ࢀߟه helloworldϕϯν • wrk -c {N} -t 8 -d 10s
-R 100000 http:/ /{host}/hello • ୯ʹʮhelloʯ͚ͩΛฦ͢ɺయܕతͳʮϕϯν൪ʯίʔυ • ͖ͬΓݴͬͯҙຯͳ͍͆
N php-fpm swoole 1 948 3187 50 1984 5935 100
1909 7303 150 Τϥʔ 6649 200 7649 500 8915
None
ࣄྫɾϕϯν·ͱΊ • ݟͯͷ௨Γɺଟॏଓ͕૿͑ͨΒ͕ࠩ͋Γ·͢ɻ • Write͕ೖΔͱɺϩδοΫʹඞཁͳ͕͔͔࣌ؒΔͷͰɺ྆ऀͷࠩ ॖ·Δ • php-fpmϓϩηεΛ૿͢ͱվળ͢Δࣄ͋Δ͕ɺ࣮ߦί ετ্͕Δ •
BacklogΛ;͢ͱόοϑΝʹͳΔ͕ɺΓ͍͔ͭ٧·Δ
• readʹ͍ͭͯαϯϓϧίʔυͷߏతʹswoole͕ζϧ͍ॴ ͋Γ·͢ • swooleርͰ݁ߏҧ͏͠Ͷɺৄ͓͘͠खݩͰࢼͯ͠Έͯ͘ ͍ͩ͞ • ʮؾ߹Λ͍Εͯͭ͘Εʯɺͬͱੑೳ͕͋Δͣʢ͔͠͠ ͦ͜·ͰखؒΛ͔͚Δͷ͔ʁʣ •
ʮͱ͜ΖͰɺ͜ΕϝʔϧϑΥʔϜͳͷ͔ʁʯʮ࣮ࡍʹmailgun ͱΈ߹ΘͤΔΜͰ͚͢Ͳɺ·͋ͦͷ͔ΘΓʹdnsΫΤϦ͍Εͯ ͋Γ·͢…ʯ
͜ͷࠩ… • swooleͷྗʂ • …ͱ·Ͱ͍͑ͳ͍͚ͲɺϩδοΫ͕ϔϏʔͰͳ͚Εswoole ͷ΄͏͕ଟগ͍ɻ • rps͕ࡾܻ͑ΔͳΒɺ༗ҙ • ٯʹɺ1ܻ2ܻͩͱେࠩͳ͍
• ଟগ͍ͱͯ͠ɺ͜Ε͕ʮͷ͍͢͝େมʯͩͬͨΒҙຯ͕ͳ ͍ • ࢲ͕͔͚ͯɺօ͞Μ͕͔͚ͳ͚Εҙຯͳ͍ • झຯͰ͔͔ͭ͑͠ͳ͍ͳΒʢࢲ͕͍͍͚Ͳʣօ͞Μʹҙຯͳ ͍ʢ͔ʣ • ଞͷΠϕϯτۦಈࣜϑϨʔϜϫʔΫͩͱ݁ߏେม
• ͱ͍͏͜ͱͰɺeasyswooleͷհʹҠΓ·͢
• ʢ͜͜·Ͱ̑ʣ
easy-swooleͷհ
easy-swooleͱ? • https:/ /www.easyswoole.com/ • swoole Λ͔ͭͬͨϑϨʔϜϫʔΫ • ेࣄʹ͑ΔʢݸਓͷײͰ͢ʣ •
؆୯γϯϓϧʂ • ݁ߏαΠτཱ͕ɺ͔͠͠େମதࠃޠ
None
ᐽՍಛੑ 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ɺUnix Socketɺ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ݚڀ։ൃνʔϜͷޮΛେ෯
ʹߴΊɺֵ৽తͳͷ։ൃʹͬͱूத͢Δ͜ͱ͕Ͱ͖·͢ɻ
None
• ͓Αͦ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ͱ͔
None
• ʮΊͬͪΌΧϥϑϧͳதࠃޠ…͚ͩͲ·͋ɺͳΜͱͳ͘Θ͔ Δɺ͍͚Δ͍͚Δʂʯ • ͨͱ͑… • --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͕ϓϩύςΟܦ༝Ͱ͑Δɻ
<?php 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͕͑·͢
None
͏Ұͭͷख๏ɺΧελϜϧʔλʔ • 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ͰͶʂ
தؒ·ͱΊ • ϝΠϯϓϩηεͷଘࡏʢΠϕϯτʣ • ΠϕϯτۦಈΛ·ͤΔϒϩοΩϯάॲཧΛ؆ศʹճආͰ͖Δ ͋Ε͜Ε • ͦͯ͠ΠϕϯτʹϓϩάϥϜΛొͯ͠αʔϏεԽ
None
• (લͷਤ֓೦ਤͰ͢ɺϝΠϯϓϩηε͋ͨΓͷߏ͕ຊͱҧ ͏ͣ) • ݸਓతʹ৭ʑΞπ͍͠ɺօ͞Μʹઆ໌Λ্͍͕ࠩ͛ͨ͠ɺ ͕࣌ؒͳ͍ͷͰলུ
• ͦͷଞʹeasy swooleʹศརػೳ͋Γ·͢ɻ
λεΫ • easy swooleʹΈࠐΈͰδϣϒϫʔΧʔ͕͋Δ • ΫϩʔδϟΛ࡞ͬͯTaskManager::async()ʹೖΕΔ͚ͩͳͷ Ͱָ • ΛΫϩʔδϟʹuseͰ͚ͭͯૹΕ·͢ •
ผ్δϣϒϫʔΧʔ͕͍Βͳ͍ͷͰ؆୯ศརʂʂ
None
λεΫͷొ 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');// +1 Cache::dec('name', 10);// -10 Cache::pull('name', 'औಘͰ͖ͳ͔ͬͨΒ');// pop Cache::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 -l 25 $ cat
bot_log |grep laravel| wc -l 333 $ cat bot_log |grep slim| wc -l 15 $ cat bot_log |grep cakephp| wc -l 22 $ cat bot_log |grep zend| wc -l 8
͍͢͝ɺظؒʹ্͕͍̎̑ͬͯ Δʂʂ • ʢظؒͱʁʁʁʣ • 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ʢʁʁʁʣͱ͔࣮༻తͳपลϥΠ ϒϥϦ
࣍ͷόʔδϣϯ̐ʂ
• ͳΜͰ͕̏εΩοϓ͞ΕΔͷ͔Θ͔ΒΜ • ੈͷதʹṖ͕ଟ͍ɻ
ϑϨʔϜϫʔΫग़࢝Ί͍ͯΔ
None
ͱ͍͏͜ͱͰ • ࠓճʮָʯͳͷͰeasyswooleΛհ͕ͨ͠ɺຊʹ༷ʑͳϥ ΠϒϥϦ͕Ͱ͍ͯΔ • ͨΓͳ͍ͷຊਓ͕ಡΈ͍͢ใνϡʔτϦΞϧ͚ͩͰ ʁʢʁʁʣ • swooleͷϏοάΣʔϒʹΔ͔͠ແ͍ʢݹ͍ʣ •
ʢࣗҎ֎ʹͬͯΔਓΈͨ͜ͱ͕ͳ͍ͷ͕Έʣ
• Tencentɺͬ͞͞ͱʢུʣͱ͔ผͷݴޠʹ͍͔ͣɺҊ֎ͪΌΜͱ ͚͍͍ͭͮͯͯ͢͝ɻ • PHPݴޠʹϋϚ͍ͬͯΔʢʣձࣾࠜੑͰPHPΛ೧͡ۂ͛Δ͔ Β͍͢͝ɻ
͍
Πϕϯτۦಈͱͦͷଞʹ͍ͭͯൺֱ • Πϕϯτۦಈͬͯ৭ʑ͋Δ • swooleΠϕϯτʴϓϩηε • reactPHPΠϕϯτ • fpmmod_phpϓϩηεʢpreforkʣ •
cgiϓϩηε
None
• શ෦͕ผΕ͍ͯΔ • ͦΕͧΕ࣮ߦ͍ͯ͠ΔPHPίʔυ͕ҟͳͬͯΑ͍ • phpࣗମprefork͞ΕΔ͕ɺຖճϓϩάϥϜىಈ͍ͯ͠Δ • ͳͷͰɺCGIɺmod_phpͱΜͳ͕ࠩগͳ͍
None
• యܕతͳΠϕϯτۦಈ • ࣮ߦ͞ΕΔPHPίʔυ͔̍ͭ͠ͳ͍ • ྫ reactPHPͳͲ • ϝΠϯϧʔϓ͕ҰͭͳͷͰɺϝΠϯϧʔϓͰͳʹ͔٧·Δॲཧ ͕͋Εશ෦ࢭ·Δ
• ຊʹϊϯϒϩοΩϯάʹॻ͚ΕޮతʹΈ͑Δ͕ɺίΞ ͕׆͔ͮ͠Β͍
None
• ΠϕϯτͱϓϩηεΛ͋Θͤͨͷɺ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 service After=network.target [Service] Type=simple LimitNOFILE=65535 WorkingDirectory=/path/to/easyswoole-sample/ ExecStart=/usr/bin/php /path/to/easyswoole-sample/easyswoole
start --pid-/path/to/easyswoole-sample/Log/pid.pid ExecReload=/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.pid Restart=always User=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