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
9.2k
phpアプリケーションをGo言語へ
yuuki takezawa
November 03, 2016
Tweet
Share
More Decks by yuuki takezawa
See All by yuuki takezawa
なぜAI時代に 「イベント」を中心に考えるのか? / Why focus on "events" in the age of AI?
ytake
4
1.6k
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
2k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
230
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
710
再考 アクターモデル/ reconsider actor model
ytake
0
1.4k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
570
Phluxorでアクターモデルを 理解・体験しよう / toolkit-for-flexible-actor-models-in-php-phluxor
ytake
1
330
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
2
1.2k
DRE/SREのプラクティス融合によるクラウドネイティブなデータ基盤作り / dre_sre
ytake
0
910
Other Decks in Programming
See All in Programming
開発組織の戦略的な役割と 設計スキル向上の効果
masuda220
PRO
10
2k
퇴근 후 1억이 거래되는 서비스 만들기 | 내가 AI를 사용하는 방법
maryang
2
330
Dive into Triton Internals
appleparan
0
400
なんでRustの環境構築してないのにRust製のツールが動くの? / Why Do Rust-Based Tools Run Without a Rust Environment?
ssssota
14
47k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
180
TFLintカスタムプラグインで始める Terraformコード品質管理
bells17
2
520
CSC509 Lecture 07
javiergs
PRO
0
250
GC25 Recap: The Code You Reviewed is Not the Code You Built / #newt_gophercon_tour
mazrean
0
140
Designing Repeatable Edits: The Architecture of . in Vim
satorunooshie
0
220
実践Claude Code:20の失敗から学ぶAIペアプログラミング
takedatakashi
18
9.4k
One Enishi After Another
snoozer05
PRO
0
170
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
680
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
97
6.3k
How STYLIGHT went responsive
nonsquared
100
5.9k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.7k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Faster Mobile Websites
deanohume
310
31k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
2.9k
How to Ace a Technical Interview
jacobian
280
24k
Raft: Consensus for Rubyists
vanstee
140
7.2k
Stop Working from a Prison Cell
hatefulcrawdad
272
21k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
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ݴޠͱ࡞Δ