Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
最近メールフォームかいてないメールフォーマーによる、ちょっとだけ変わった一応PHPのメールフォ...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
uzulla
June 15, 2018
Programming
8.3k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
最近メールフォームかいてないメールフォーマーによる、ちょっとだけ変わった一応PHPのメールフォーム(?)のお話 〜副題 最近swooleがたのしいです〜
at 全然野菜(PHPCon Fukuoka 2018 非公式 前々夜祭)
20min talk
https://pepabo.connpass.com/event/85144/
uzulla
June 15, 2018
More Decks by uzulla
See All by uzulla
ALL CODE BASE ARE BELONG TO STUDY
uzulla
30
7.9k
バイブスあるコーディングで ~PHP~ 便利ツールをつくるプラクティス
uzulla
1
610
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
2.9k
似たもの同士のPerlとPHP
uzulla
1
320
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
240
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
340
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
240
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
3.4k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
6
1.5k
Other Decks in Programming
See All in Programming
R8 の設定見直しでアプリサイズ削減
andpad
0
170
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
280
カツオ、ご期待ください
suneo3476
0
150
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
460
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
160
SREの越境 / SRE Collaboration
y0hgi
2
300
Workers Cache を知る
syumai
0
340
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
110
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.8k
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2.2k
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
350
Featured
See All Featured
Bash Introduction
62gerente
615
220k
Done Done
chrislema
187
17k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
530
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
740
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
First, design no harm
axbom
PRO
2
1.3k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
540
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
320
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
570
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
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