Slide 1

Slide 1 text

phpΞϓϦέʔγϣϯΛ Goݴޠ΁ go func() { messages <- "php" }() yuuki takezawa phpcon 2016

Slide 2

Slide 2 text

GoݴޠΛ࠾༻͢Δ͜ͱʹͳͬͨഎܠ

Slide 3

Slide 3 text

ڊେͳαʔϏεͷݶք

Slide 4

Slide 4 text

ڊେαʔϏεʹΑΔ໰୊ • 1Օॴͷमਖ਼͕க໋తͳ໰୊ΛҾ͖ى͜͢έʔε • ෳࡶԽ͢Δ࢓༷ʹରԠ͢Δҝͷ࣮૷͕ύϑΥʔϚϯε ʹӨڹΛ༩͑࢝Ίͨ • ڊେʹͳΓ͗ͨ͢σʔλϕʔε • ୲౰֎ͷαʔϏε࢓༷͕Θ͔Βͳ͚Ε͹मਖ਼Ͱ͖ͳ͍ ঢ়ଶ • API͕͘͢ͳ͘ɺଟ͕͘σʔλϕʔεʹґଘ • ϏδωεͷมԽʹ௥ैͰ͖ͳ͍ঢ়ଶ • େྔσʔλͷόονॲཧ

Slide 5

Slide 5 text

໰୊ʹཱͪ޲͔͏ • σʔλϕʔεࢀরͷ੾Γ཭͠ • APIͷ੔උ json, xml, etc… • ΫϥΠΞϯτͷॲཧΛ؆ུԽ͢ΔҝʹɺHATEOAS΁
 (औΓ૊Έத) • σʔλϕʔεࣗମͷ෼ׂ
 (ςʔϒϧͷ࠶ઃܭɺ໨తผʹ෼ׂɺNoSQLซ༻) • ԣஅతʹؔΘΔαʔϏεͱͷ࿈ܞ
 (message queue, ฒྻॲཧ)

Slide 6

Slide 6 text

σʔλϕʔεࢀরͷ੾Γ཭͠ • ιʔείʔυͷ͍ͨΔͱ͜Ζʹ͋ΔσʔλϕʔεࢀরΛ
 ந৅ԽɺDependency Injection΁ • σʔλϕʔε΁઀ଓΛߦ͍ͬͯΔίʔυ͔Βɺ
 ֎తཁҼΛ੾Γ཭͠ • ΞϓϦέʔγϣϯߏ଄Λ·ͣ͸ϨΠϠʔԽ • ঃʑʹAPIࢀর΁ͱ੾Γସ͍͑ͯ͘ • PHPΞϓϦέʔγϣϯΛૄ݁߹ʹ

Slide 7

Slide 7 text

class PointBalance { /** @var PointRepositoryInterface */ protected $repository; /** * @param PointRepositoryInterface $repository */ public function __construct(PointRepositoryInterface $repository) { $this->repository = $repository; } // snippet }

Slide 8

Slide 8 text

Controller / Action Domain Infrastructure MySQL API Elasticsearch Aspect

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

APIͷ੔උ • ଞαʔϏεͷ஌ࣝΛෆཁʹ
 (URLͷߏங΍ɺͲΜͳAPIͰͲΜͳ͜ͱ͕Ͱ͖Δͷʁ) • ϦΫΤετ਺ͷ࡟ݮ • ΤϯυϙΠϯτʹಈࢺ͸࢖ΘͣɺϝιουͰදݱ͢Δ • ڞ௨Ͱར༻͢Δ΋ͷ͸ίϯϙʔωϯτԽ • ݹ͍APIͳͲɺଟ͘ͷαʔϏε͕ґଘ͍ͯ͠Δ΋ͷ͸ͳ ͔ͳ͔೉͍͠ • ύϑΥʔϚϯε͕ϘτϧωοΫͳ΋ͷ͸replace

Slide 11

Slide 11 text

{ "id": 1598, "user_id": 123, "title": "ίϝϯτʹͨ͠Α", "content": "ϝʔϧ͕དྷͳ͍ΑͶ", "tags": [ { "id": 5098, "name": "ඒന" } ], "created_at": "2016-10-12 17:31:50" }

Slide 12

Slide 12 text

{ "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" } } }

Slide 13

Slide 13 text

navi menu content content

Slide 14

Slide 14 text

ϑϩϯτͰར༻͞ΕΔAPI • ϑϩϯτʹग़ྗ͞ΕΔ΋ͷ͚ͩͰ͸ͳ͘ɺ
 ͦͷޙΖʹ߇͑Δ΋ͷ • Ϣʔβʔొ࿥৘ใ • ϝʔϧૹ৴ • ͳʹ͔͠Βͷߦಈʹ൐͏Ճࢉݮࢉ • ඇಉظɺϦΞϧλΠϜ • τϥϯβΫγϣϯεΫϦϓτ • ฒྻϦΫΤετʹ଱͑͏Δ΋ͷ • ϑϩϯτ͔Β੾Γ཭͢͜ͱͰదࡐదॴͳݴޠ࠾༻

Slide 15

Slide 15 text

େྔͷϦΫΤετΛޮ཰ྑ͘ࡹ͖͍ͨ

Slide 16

Slide 16 text

Nginx + php-fpm Response time: 0.01 secs Transaction rate: 384.48 trans/sec

Slide 17

Slide 17 text

େ͖ͳ͸໰୊ͳ͠ • ΞΫηε͕ଟ͘ͳΕ͹ɺ୆਺Λ૿΍͢ • opcache΋ಋೖ͠(PHP7)ɺߴ଎ͳϨεϙϯε
 • ࣮૷໘ͰͷόάΛ࠷খݶʹ৯͍ࢭΊ͍ͨ • PHP7ʹͳΓɺݫ֨Ͱ͸͋Δ͕ɺ
 ։ൃऀશһ͕ཧղ͍ͯ͠ΔΘ͚Ͱ͸ແ͍ • ϦΞϧλΠϜॲཧΛͱʹ͔͘ૣ͘ • ඞཁͳ৘ใΛଋͶͯฦ٫͍ͨ͠

Slide 18

Slide 18 text

γϯϓϧɺฒߦ͔ͭߴ଎Ͱ੩తܕ෇͚ݴޠ

Slide 19

Slide 19 text

Go • webαʔόͳͲ͕ෆཁͰ୯ମͰಈ࡞͢Δ • جຊ͸γϯάϧόΠφϦ഑෍ͷҝɺϦϦʔε͕༰қ • ίϯύΠϧ͕ૣ͘ɺΫϩείϯύΠϧ • ϝϞϦϦʔΫʹͳΓಘΔ΋ͷ͕ഉআ͞Ε͍ͯΔ • 1αʔόͰෳ਺ىಈͤ͞Δ͜ͱ͕Ͱ͖Δ • ίϯύΠϧͱ࣮ߦ͕ಉ࣌ʹͰ͖ΔͨΊɺ
 LLݴޠ։ൃऀͰ΋؆୯ • Ϋϥε͕ແ͍

Slide 20

Slide 20 text

// linux޲͚΍windows޲͚ͳͲ༷ʑͳOSʹରԠ $ GOOS=linux GOARCH=amd64 go build -tags=production app.go

Slide 21

Slide 21 text

Struct • ΫϥεͰ͸ͳ͍ • ໊લͱܕͷू·Γ • ઌ಄͕େจࣈͷ΋ͷ͸public 
 ͦ͏Ͱ͸ͳ͍΋ͷ͸private • ίϯετϥΫλ͸ଘࡏͤͣɺܧঝ΋ͳ͍ • ߏ଄ମΛຒΊࠐΜͰར༻͢Δ

Slide 22

Slide 22 text

type Item struct { Language } type Language struct { Name string } Item{Language{"PHP"}}

Slide 23

Slide 23 text

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 }

Slide 24

Slide 24 text

goroutine • ಉ࣌ʹෳ਺ͷλεΫΛॲཧ • ॲཧΛ෼ׂ͍ͯ͘͠ • εϨουͷΑ͏ʹ1εϨου্Ͱෳ਺ಈ࡞ • ಄ʹgo Λ͚ͭΔ͚ͩ go func() • ଴͕ͪ࣌ؒൃੜͯ͠͠·͏Α͏ͳॲཧΛඇಉظͰ • ฒߦॲཧ

Slide 25

Slide 25 text

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") }

Slide 26

Slide 26 text

ฒߦͱฒྻ • ฒߦ
 ࣮ߦঢ়ଶΛෳ਺อͯΔͳΒ • ฒྻ
 ෳ਺ͷಈ࡞Λಉ࣌ʹग़དྷΔ
 • GoݴޠͷฒߦੑΛө૾Խ͢Δ
 http://postd.cc/go_concurrency_visualize/

Slide 27

Slide 27 text

channel • <- (໼ҹͷํ޲ʹྲྀΕΔ) • goroutine ؒͰ΍ΓऔΓΛߦ͏ • phpͰ͸೉͍͜͠ͱΛΧόʔ͢Δ • ΩϡʔΠϯάɺॲཧ଴ͪঢ়ଶͳͲΛ࡞Δ

Slide 28

Slide 28 text

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 }

Slide 29

Slide 29 text

defer ͱ panic • defer: ϝιου͕ऴྃ͢Δࡍʹίʔϧ͞ΕΔ • σʔλϕʔεͳͲͷ੾அͳͲॲཧͷ஗Ԇʹ࢖͏ • panic͸runtime errorʹ͋ͨΓɺ
 ࣮ߦ͕೉͍͠৔߹ʹͷΈར༻͢Δ • panic࣌ʹ΋defer͕ίʔϧ͞ΕΔ • ΤϥʔॲཧΛ͢ΔͷͰ͋Ε͹errorΛ໭͢ • panic͔Β͔ͳΒͣrecover()͢Δ

Slide 30

Slide 30 text

nginxΛ࢖ͬͨϩʔυόϥϯγϯά

Slide 31

Slide 31 text

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 ""; } }

Slide 32

Slide 32 text

Nginx + go Response time: 0.00 secs Transaction rate: 2142.67 trans/sec

Slide 33

Slide 33 text

খ͞ͳͱ͜Ζ͔Βஔ͖׵͑Λ࢝Ίͨ • PHPͰ࣮ߦ͞Ε͍ͯͨେྔσʔλͷόονॲཧ
 ਺͔͔࣌ؒΓɺσʔλͷྔ͕૿͑Δ͜ͱͰߋʹ࣌ؒ
 ϝϞϦ͕৺഑(݅਺͕૿͑Δ͝ͱʹ૿Ճ) • Goʹஔ͖׵͑ɺϝϞϦ࢖༻ྔ͕ܹݮ
 ਺͕࣌ؒ୹ॖ
 σʔλϕʔεʹΑͬͯ͸͋·ΓมΘΒͳ͍͜ͱ΋͋ͬͨ • web։ൃʹదͨ͠ඪ४ϥΠϒϥϦ͕ଟ͘ɺ
 ίʔυ΋ಡΈ΍͘͢ɺ݁ՌҰ෦Ͱ࠾༻

Slide 34

Slide 34 text

ϑϨʔϜϫʔΫ echo

Slide 35

Slide 35 text

echo • ϚΠΫϩϑϨʔϜϫʔΫͰɺlumen΍zend expressive ͱಉ͡ײ֮Ͱ։ൃ͕Ͱ͖Δ • fasthttp͕ΦϓγϣϯͰ࢖͑Δ • grace͕͙͢ʹ࢖͑Δঢ়ଶͰɺͱʹ͔͘؆୯ • ඞཁͳ΋ͷ͸ࣗ෼Ͱ૊ΈࠐΉ • ܰྔͳAPIͰ͋Ε͹ൺֱత୹࣌ؒͰ࣮૷Մೳ

Slide 36

Slide 36 text

ಋೖલʹ࣮ફ • ϓϥΠϕʔτͰ։ൃ͍ͯͨ͠ΞϓϦͷAPIʹ·ͣಋೖ • ҆ఆՔಇͱ࣮૷͕ૣ͍ • OAuthαʔό࣮૷ • ߴෛՙͰ΋ඇৗʹ҆ఆ • facebookgo/inject • ΦϒδΣΫτࢦ޲ϥΠΫʹ࣮૷͍͕ͯͨ͠ɺ
 Goͷ࡞๏ʹͷͬͨ΄͏͕γϯϓϧ • ϦϑϨΫγϣϯ͸ۃྗ࢖Θͳ͍

Slide 37

Slide 37 text

Go goroutine API API Database queue

Slide 38

Slide 38 text

վળ • ΑΓૣ͘ɺݎ࣮ͳΞϓϦέʔγϣϯ • ͦΕͧΕͷαʔϏεͷॲཧʹదͨ͠΋ͷΛಋೖ • ϦϦʔε࡞ۀͷ୯७Խ
 ίϯύΠϧͯ͠഑෍΁(CIͳͲ) • supervisord • ύϑΥʔϚϯεվળ গͣͭ͠

Slide 39

Slide 39 text

๊͍͑ͯΔ໰୊ • ؀ڥઃఆ஋ͳͲͷڞ༗
 viper? • όΠφϦʹ͢΂ͯͷσʔλΛ࣋ͨͤΔ͔
 go-bindata etc • ϑϥάͱ؀ڥ͝ͱͷઃఆ஋
 ιʔείʔυ಺ʹηΩϡΞͳ৘ใΛؚΊΒΕͳ͍ • ؆୯ͱ͸ݴͬͯ΋ͳ͔ͳ͔։ൃऀ͕૿͑ͳ͍

Slide 40

Slide 40 text

Request Response web server + php

Slide 41

Slide 41 text

$_SERVER net/http application server΁

Slide 42

Slide 42 text

phpΛิ͍ɺͦΕΛαʔϏεͱͯ͠׆͔͢

Slide 43

Slide 43 text

վળ͸࢝·ͬͨ͹͔Γ ՝୊ղܾΛPHP+αͰ (దࡐదॴ)

Slide 44

Slide 44 text

PHPΞϓϦέʔγϣϯΛGoݴޠͱ࡞Δ