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
phpアプリケーションをGo言語へ
Search
yuuki takezawa
November 03, 2016
Programming
9.2k
9
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
phpアプリケーションをGo言語へ
yuuki takezawa
November 03, 2016
More Decks by yuuki takezawa
See All by yuuki takezawa
なぜAI時代に 「イベント」を中心に考えるのか? / Why focus on "events" in the age of AI?
ytake
4
2.1k
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
3k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
340
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
970
再考 アクターモデル/ reconsider actor model
ytake
0
1.6k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
670
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
390
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.4k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
1.1k
Other Decks in Programming
See All in Programming
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
250
Go 1.27 における memory allocation の高速化
andpad
0
120
Google Apps Script で Ruby を動かす
kawahara
0
140
Lean は証明の正しさを確認するためだけのツールって思ってませんか?
inoueasei
1
150
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
150
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
150
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
210
AIが無かった頃の素敵な出会いの話
codmoninc
1
400
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
120
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
340
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.9k
Featured
See All Featured
Six Lessons from altMBA
skipperchong
29
4.4k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
850
Balancing Empowerment & Direction
lara
6
1.2k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
200
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Color Theory Basics | Prateek | Gurzu
gurzu
0
410
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
520
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
230
Transcript
phpΞϓϦέʔγϣϯΛ Goݴޠ go func() { messages <- "php" }() yuuki
takezawa phpcon 2016
GoݴޠΛ࠾༻͢Δ͜ͱʹͳͬͨഎܠ
ڊେͳαʔϏεͷݶք
ڊେαʔϏεʹΑΔ • 1Օॴͷमਖ਼͕க໋తͳΛҾ͖ى͜͢έʔε • ෳࡶԽ͢Δ༷ʹରԠ͢Δҝͷ࣮͕ύϑΥʔϚϯε ʹӨڹΛ༩͑࢝Ίͨ • ڊେʹͳΓ͗ͨ͢σʔλϕʔε • ୲֎ͷαʔϏε༷͕Θ͔Βͳ͚Εमਖ਼Ͱ͖ͳ͍
ঢ়ଶ • API͕͘͢ͳ͘ɺଟ͕͘σʔλϕʔεʹґଘ • ϏδωεͷมԽʹैͰ͖ͳ͍ঢ়ଶ • େྔσʔλͷόονॲཧ
ʹཱ͔ͪ͏ • σʔλϕʔεࢀরͷΓ͠ • APIͷඋ json, xml, etc… • ΫϥΠΞϯτͷॲཧΛ؆ུԽ͢ΔҝʹɺHATEOAS
(औΓΈத) • σʔλϕʔεࣗମͷׂ (ςʔϒϧͷ࠶ઃܭɺతผʹׂɺNoSQLซ༻) • ԣஅతʹؔΘΔαʔϏεͱͷ࿈ܞ (message queue, ฒྻॲཧ)
σʔλϕʔεࢀরͷΓ͠ • ιʔείʔυͷ͍ͨΔͱ͜Ζʹ͋ΔσʔλϕʔεࢀরΛ நԽɺDependency Injection • σʔλϕʔεଓΛߦ͍ͬͯΔίʔυ͔Βɺ ֎తཁҼΛΓ͠ • ΞϓϦέʔγϣϯߏΛ·ͣϨΠϠʔԽ
• ঃʑʹAPIࢀরͱΓସ͍͑ͯ͘ • PHPΞϓϦέʔγϣϯΛૄ݁߹ʹ
class PointBalance { /** @var PointRepositoryInterface */ protected $repository; /**
* @param PointRepositoryInterface $repository */ public function __construct(PointRepositoryInterface $repository) { $this->repository = $repository; } // snippet }
Controller / Action Domain Infrastructure MySQL API Elasticsearch Aspect
None
APIͷඋ • ଞαʔϏεͷࣝΛෆཁʹ (URLͷߏஙɺͲΜͳAPIͰͲΜͳ͜ͱ͕Ͱ͖Δͷʁ) • ϦΫΤετͷݮ • ΤϯυϙΠϯτʹಈࢺΘͣɺϝιουͰදݱ͢Δ • ڞ௨Ͱར༻͢ΔͷίϯϙʔωϯτԽ
• ݹ͍APIͳͲɺଟ͘ͷαʔϏε͕ґଘ͍ͯ͠Δͷͳ ͔ͳ͔͍͠ • ύϑΥʔϚϯε͕ϘτϧωοΫͳͷreplace
{ "id": 1598, "user_id": 123, "title": "ίϝϯτʹͨ͠Α", "content": "ϝʔϧ͕དྷͳ͍ΑͶ", "tags":
[ { "id": 5098, "name": "ඒന" } ], "created_at": "2016-10-12 17:31:50" }
{ "id": 3746, "user_id": 123, "title": "ςετ", "content": "aaa", "tags":
[ { "id": 6081, "name": "ΞϩϚΦΠϧ", "_links": { "self": { "href": "http://example.com/tags/6081", "method": "GET" } } } ], "created_at": "2016-10-14 16:57:37", "_links": { "self": { "href": "http://example.com/3746", "method": "GET" } } }
navi menu content content
ϑϩϯτͰར༻͞ΕΔAPI • ϑϩϯτʹग़ྗ͞ΕΔͷ͚ͩͰͳ͘ɺ ͦͷޙΖʹ߇͑Δͷ • Ϣʔβʔొใ • ϝʔϧૹ৴ • ͳʹ͔͠Βͷߦಈʹ͏Ճࢉݮࢉ
• ඇಉظɺϦΞϧλΠϜ • τϥϯβΫγϣϯεΫϦϓτ • ฒྻϦΫΤετʹ͑͏Δͷ • ϑϩϯτ͔ΒΓ͢͜ͱͰదࡐదॴͳݴޠ࠾༻
େྔͷϦΫΤετΛޮྑ͘ࡹ͖͍ͨ
Nginx + php-fpm Response time: 0.01 secs Transaction rate: 384.48
trans/sec
େ͖ͳͳ͠ • ΞΫηε͕ଟ͘ͳΕɺΛ૿͢ • opcacheಋೖ͠(PHP7)ɺߴͳϨεϙϯε • ࣮໘ͰͷόάΛ࠷খݶʹ৯͍ࢭΊ͍ͨ • PHP7ʹͳΓɺݫ֨Ͱ͋Δ͕ɺ ։ൃऀશһ͕ཧղ͍ͯ͠ΔΘ͚Ͱແ͍
• ϦΞϧλΠϜॲཧΛͱʹ͔͘ૣ͘ • ඞཁͳใΛଋͶͯฦ٫͍ͨ͠
γϯϓϧɺฒߦ͔ͭߴͰ੩తܕ͚ݴޠ
Go • webαʔόͳͲ͕ෆཁͰ୯ମͰಈ࡞͢Δ • جຊγϯάϧόΠφϦͷҝɺϦϦʔε͕༰қ • ίϯύΠϧ͕ૣ͘ɺΫϩείϯύΠϧ • ϝϞϦϦʔΫʹͳΓಘΔͷ͕ഉআ͞Ε͍ͯΔ •
1αʔόͰෳىಈͤ͞Δ͜ͱ͕Ͱ͖Δ • ίϯύΠϧͱ࣮ߦ͕ಉ࣌ʹͰ͖ΔͨΊɺ LLݴޠ։ൃऀͰ؆୯ • Ϋϥε͕ແ͍
// linux͚windows͚ͳͲ༷ʑͳOSʹରԠ $ GOOS=linux GOARCH=amd64 go build -tags=production app.go
Struct • ΫϥεͰͳ͍ • ໊લͱܕͷू·Γ • ઌ಄͕େจࣈͷͷpublic ͦ͏Ͱͳ͍ͷprivate •
ίϯετϥΫλଘࡏͤͣɺܧঝͳ͍ • ߏମΛຒΊࠐΜͰར༻͢Δ
type Item struct { Language } type Language struct {
Name string } Item{Language{"PHP"}}
func handler(w http.ResponseWriter, r *http.Request) { person := &Person{"yuuki", "takezawa"}
fullName(person) } func fullName(name UserName) { fmt.Println(name.Name()) } type Person struct { FirstName string LastName string } func (p *Person) Name() string { return p.FirstName + " " + p.LastName } type UserName interface { Name() string }
goroutine • ಉ࣌ʹෳͷλεΫΛॲཧ • ॲཧΛׂ͍ͯ͘͠ • εϨουͷΑ͏ʹ1εϨου্Ͱෳಈ࡞ • ಄ʹgo Λ͚ͭΔ͚ͩ
go func() • ͕ͪ࣌ؒൃੜͯ͠͠·͏Α͏ͳॲཧΛඇಉظͰ • ฒߦॲཧ
func f(from string) { for i := 0; i <
3; i++ { fmt.Println(from, ":", i) } } // ॱ൪อূ͞Ε·ͤΜ fun main() { go f("routine") go f("routine_one") go f(“routine_two") }
ฒߦͱฒྻ • ฒߦ ࣮ߦঢ়ଶΛෳอͯΔͳΒ • ฒྻ ෳͷಈ࡞Λಉ࣌ʹग़དྷΔ • GoݴޠͷฒߦੑΛө૾Խ͢Δ http://postd.cc/go_concurrency_visualize/
channel • <- (ҹͷํʹྲྀΕΔ) • goroutine ؒͰΓऔΓΛߦ͏ • phpͰ͍͜͠ͱΛΧόʔ͢Δ •
ΩϡʔΠϯάɺॲཧͪঢ়ଶͳͲΛ࡞Δ
func read(r io.Reader) <-chan message { lines := make(chan message)
go func() { defer close(lines) scan := bufio.NewScanner(r) for scan.Scan() { lines <- message(scan.Bytes()) } }() return lines }
defer ͱ panic • defer: ϝιου͕ऴྃ͢Δࡍʹίʔϧ͞ΕΔ • σʔλϕʔεͳͲͷஅͳͲॲཧͷԆʹ͏ • panicruntime
errorʹ͋ͨΓɺ ࣮ߦ͕͍͠߹ʹͷΈར༻͢Δ • panic࣌ʹdefer͕ίʔϧ͞ΕΔ • ΤϥʔॲཧΛ͢ΔͷͰ͋ΕerrorΛ͢ • panic͔Β͔ͳΒͣrecover()͢Δ
nginxΛͬͨϩʔυόϥϯγϯά
upstream go_http { server 127.0.0.1:8080; server 127.0.0.1:8081; keepalive 300; }
server { listen 80; server_name go.app; charset utf-8; access_log off; error_log /dev/null crit; location / { proxy_pass http://go_http; proxy_http_version 1.1; proxy_set_header Connection ""; } }
Nginx + go Response time: 0.00 secs Transaction rate: 2142.67
trans/sec
খ͞ͳͱ͜Ζ͔Βஔ͖͑Λ࢝Ίͨ • PHPͰ࣮ߦ͞Ε͍ͯͨେྔσʔλͷόονॲཧ ͔͔࣌ؒΓɺσʔλͷྔ͕૿͑Δ͜ͱͰߋʹ࣌ؒ ϝϞϦ͕৺(͕݅૿͑Δ͝ͱʹ૿Ճ) • Goʹஔ͖͑ɺϝϞϦ༻ྔ͕ܹݮ ͕࣌ؒॖ σʔλϕʔεʹΑͬͯ͋·ΓมΘΒͳ͍͜ͱ͋ͬͨ •
web։ൃʹదͨ͠ඪ४ϥΠϒϥϦ͕ଟ͘ɺ ίʔυಡΈ͘͢ɺ݁ՌҰ෦Ͱ࠾༻
ϑϨʔϜϫʔΫ echo
echo • ϚΠΫϩϑϨʔϜϫʔΫͰɺlumenzend expressive ͱಉ͡ײ֮Ͱ։ൃ͕Ͱ͖Δ • fasthttp͕ΦϓγϣϯͰ͑Δ • grace͕͙͢ʹ͑Δঢ়ଶͰɺͱʹ͔͘؆୯ •
ඞཁͳͷࣗͰΈࠐΉ • ܰྔͳAPIͰ͋Εൺֱత࣌ؒͰ࣮Մೳ
ಋೖલʹ࣮ફ • ϓϥΠϕʔτͰ։ൃ͍ͯͨ͠ΞϓϦͷAPIʹ·ͣಋೖ • ҆ఆՔಇͱ࣮͕ૣ͍ • OAuthαʔό࣮ • ߴෛՙͰඇৗʹ҆ఆ •
facebookgo/inject • ΦϒδΣΫτࢦϥΠΫʹ࣮͍͕ͯͨ͠ɺ Goͷ࡞๏ʹͷͬͨ΄͏͕γϯϓϧ • ϦϑϨΫγϣϯۃྗΘͳ͍
Go goroutine API API Database queue
վળ • ΑΓૣ͘ɺݎ࣮ͳΞϓϦέʔγϣϯ • ͦΕͧΕͷαʔϏεͷॲཧʹదͨ͠ͷΛಋೖ • ϦϦʔε࡞ۀͷ୯७Խ ίϯύΠϧͯ͠(CIͳͲ) • supervisord
• ύϑΥʔϚϯεվળ গͣͭ͠
๊͍͑ͯΔ • ڥઃఆͳͲͷڞ༗ viper? • όΠφϦʹͯ͢ͷσʔλΛ࣋ͨͤΔ͔ go-bindata etc • ϑϥάͱڥ͝ͱͷઃఆ
ιʔείʔυʹηΩϡΞͳใΛؚΊΒΕͳ͍ • ؆୯ͱݴͬͯͳ͔ͳ͔։ൃऀ͕૿͑ͳ͍
Request Response web server + php
$_SERVER net/http application server
phpΛิ͍ɺͦΕΛαʔϏεͱͯ͠׆͔͢
վળ࢝·͔ͬͨΓ ՝ղܾΛPHP+αͰ (దࡐదॴ)
PHPΞϓϦέʔγϣϯΛGoݴޠͱ࡞Δ