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.1k
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.4k
PHPでアクターモデルを活用したSagaパターンの実践法 / php-saga-pattern-with-actor-model
ytake
0
1.9k
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
210
PHPでアクターモデルを理解・体験しよう / Understand and experience the actor model in PHP
ytake
2
690
再考 アクターモデル/ reconsider actor model
ytake
0
1.4k
GoとアクターモデルでES+CQRSを実践! / proto_actor_es_cqrs
ytake
1
560
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
900
Other Decks in Programming
See All in Programming
Чего вы не знали о строках в Python – Василий Рябов, PythoNN
sobolevn
0
160
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
2
450
階層構造を表現するデータ構造とリファクタリング 〜1年で10倍成長したプロダクトの変化と課題〜
yuhisatoxxx
3
920
Local Peer-to-Peer APIはどのように使われていくのか?
hal_spidernight
2
450
いま中途半端なSwift 6対応をするより、Default ActorやApproachable Concurrencyを有効にしてからでいいんじゃない?
yimajo
2
340
CSC305 Lecture 03
javiergs
PRO
0
230
Django Ninja による API 開発効率化とリプレースの実践
kashewnuts
0
930
Catch Up: Go Style Guide Update
andpad
0
170
タスクの特性や不確実性に応じた最適な作業スタイルの選択(ペアプロ・モブプロ・ソロプロ)と実践 / Optimal Work Style Selection: Pair, Mob, or Solo Programming.
honyanya
3
140
実践AIチャットボットUI実装入門
syumai
7
2.5k
フロントエンド開発に役立つクライアントプログラム共通のノウハウ / Universal client-side programming best practices for frontend development
nrslib
7
3.9k
アメ車でサンノゼを走ってきたよ!
s_shimotori
0
140
Featured
See All Featured
A Tale of Four Properties
chriscoyier
160
23k
Scaling GitHub
holman
463
140k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
Writing Fast Ruby
sferik
629
62k
How to Ace a Technical Interview
jacobian
280
24k
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
The Power of CSS Pseudo Elements
geoffreycrofte
79
6k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Done Done
chrislema
185
16k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
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ݴޠͱ࡞Δ