Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
GoとGAEによるWebアプリケーション開発(Go Con 2016 Spring)
Tatsuya Tsuruoka
April 23, 2016
Programming
12
7.6k
GoとGAEによるWebアプリケーション開発(Go Con 2016 Spring)
2016年4月23日の Go Conference 2016 Spring の発表資料です。
Tatsuya Tsuruoka
April 23, 2016
Tweet
Share
More Decks by Tatsuya Tsuruoka
See All by Tatsuya Tsuruoka
ttsuruoka
19
11k
ttsuruoka
20
47k
ttsuruoka
17
24k
ttsuruoka
2
1.7k
ttsuruoka
0
180
Other Decks in Programming
See All in Programming
grapecity_dev
0
180
deepflow
3
590
bbatsov
0
110
abeta
1
160
manfredsteyer
PRO
0
140
zwass
0
350
mploed
3
160
legalforce
PRO
0
610
dbrumann
0
110
tetsukick
0
180
heistak
2
130
danilop
0
220
Featured
See All Featured
jasonvnalue
82
8.1k
caitiem20
308
17k
holman
461
280k
scottboms
251
11k
shpigford
165
19k
rocio
155
11k
lara
590
61k
chrislema
173
14k
jlugia
217
16k
addyosmani
311
21k
revolveconf
200
9.7k
edds
56
9.4k
Transcript
(Pͱ("&ʹΑΔ 8FCΞϓϦέʔγϣϯ։ൃ 2016/04/23
ࣗݾհ 2 • גࣜձࣾικ ˍ גࣜձࣾϝϧΧϦ • ٕज़తͳҙࢥܾఆͱνʔϜ࡞Γ͕ࣄͰ͢ !UUTVSVPLB Ԭ
ୡ
ࠓճ͓͍͑ͨ͜͠ͱ 3 1. Google App Engine / Go Ͱ ݱ࣮తͳ
Web ΞϓϦΛ։ൃ͠ɺӡ༻͍ͯ͘͜͠ͱ͕Ͱ͖Δ 2. ͦͯ͠ Go ʹΑΔ Web ΞϓϦ։ൃ͕ɺ ࠓޙ·͢·͋ͨ͢Γ·͑ʹͳ͍ͬͯ͘
INDEX Why Google App Engineʁ εέʔϥϏϦςΟʢΩϡʔͱӬଓԽʣ ϩάੳͱӡ༻
Why GAE? - GAE ͱ 5 • GAE Web
ΞϓϦͷͨΊͷ PaaS • ༷ʑͳ։ൃݴޠʹରԠ͓ͯ͠Γ Go ͦͷ͏ͪͷͻͱͭ • ࣮ݱͰ͖Δ͜ͱ • ۃΊͯߴ͍εέʔϥϏϦςΟ • req/sec ेສreq/sec ಉ͡Α͏ʹѻ͑Δ • Google ϨϕϧͷՄ༻ੑ • োʹΑͬͯαʔϏε͕ఀࢭ͢Δ͜ͱك • ϝϯςφϯεϑϦʔ • ࠷ॳʹΞʔΩςΫνϟΛܾΊΕ͋ͱ͏ख͕͔͔Βͳ͍
Why GAE? - GAE ͱ 6 • ࣮ࡍʹ GAE ͰͲΜͳ
Web ΞϓϦΛ࡞͍͚ͬͯΔʁ • ࣄྫɿSnapchatɺIngress • ผͷར༻Ϣʔβ͕1ԯਓΛ͑Δنͷ࣮͕ɺ͢Ͱʹ͋Δ ※ͨͩ͠ݴޠ Go Ͱͳ͍ͱࢥΘΕ·͢ • ϝϧΧϦࢠձࣾͷ৽نࣄۀʮϝϧΧϦ Ξοςʯ GAE Λ࠷େݶʹར༻ • ΠϯϑϥΤϯδχΞ 0 ਓ • ϦϦʔε͔Βͷ1ϲ݄ؒʹٸܹͳΞΫηε૿ͳͲͰࠔͬͨ͜ͱҰͳ͠ • μϯλΠϜθϩɻܭըఀࢭͳ͠ • → ݱ࣮తͳ Web ΞϓϦΛ࡞ΔͨΊͷػೳඋΘ͍ͬͯΔ
Why GAE? 7 • ࠓճɺGAE ͷػೳΛհ͢ΔͨΊʹ Web ΞϓϦΛߟ͑ͯΈΔ • ྫ͑ɺ͍·Γ্͕͍ͬͯΔ
Bot ΞϓϦ 4݄7 LINE BOT API ެ։ɺ4݄13 Facebook bots on Messenger ެ։ • → ͜ͷ Bot ΞϓϦΛ GAE ͰϋΠεέʔϥϒϧʹ࡞Δͱͨ͠Β...
εέʔϥϏϦςΟʢΩϡʔͱӬଓԽʣ
εέʔϥϏϦςΟ - ୯७ͳ Bot 9 • ػೳɿ • νϟοταʔόʢ͜ͷྫͰLINEʣ͔Β ίʔϧόοΫΛड͚औΓɺ
ϢʔβͷϝοηʔδͳͲΛऔಘͰ͖Δ • ϝοηʔδΛݩʹԿΒ͔ͷॲཧΛͯ͠ɺ Ϣʔβʹฦ৴Ͱ͖Δ
εέʔϥϏϦςΟ - ୯७ͳ Bot 10 • ίʔϧόοΫΛϋϯυϦϯά͢Δ func init() {
http.HandleFunc("/line/callback", receiveLine) } func receiveLine(w http.ResponseWriter, r *http.Request) { ... } • func init GAE/Go ΞϓϦͷཪଆ͔ΒݺΕΔॏཁͳؔ • func receiveLine ͷதͰૹΒΕͯ͘ΔϝοηʔδΛॲཧͯ͠ฦ৴ͨ͠Γ͢Δ
εέʔϥϏϦςΟ - ୯७ͳ Bot 11 • ͜ΕΛσϓϩΠ͢Δ͚ͩͰ… ʢ͍͔ͭ͘՝͋Δͷͷʣεέʔϥϒϧͳ Bot ͕Ͱ͖͕͋Γ
• ͜ͷ࣌ͷεέʔϥϏϦςΟɿ • ༑ୡ͕͍ͳ͍ͱ͖ → Πϯελϯεىಈ͍ͯ͠ͳ͍ • ༑ୡ͕૿͑ͨΓϝοηʔδ͕ૹΒΕͯ͘ΔͱίʔϧόοΫ͕ୟ͔ΕΔ → ༑ୡͷ૿͑ํϝοηʔδͷྲྀྔʹ߹ΘͤͯΠϯελϯε͕ࣗಈͰ૿ݮ • Πϯελϯεͷىಈेʙ200msͳͷͰऔΓ͜΅͠ͳ͠ • Πϯελϯεͷىಈ࣮࣌ؒݴޠʹΑͬͯҟͳΔ • ͪΖΜ Go ͕࠷
εέʔϥϏϦςΟ - ୯७ͳ Bot 12 • ՝ɿ • ͻͱͭͷϦΫΤετΛॲཧ͢Δͷʹ͕͔͔࣌ؒͬͯ͠·͏ͱ͖ •
GAE ଆɿϦΫΤετ60ඵͰλΠϜΞτ͢Δ • LINE BOT ଆɿ 1ϦΫΤετ10ඵͰλΠϜΞτ͢Δ • → ίʔϧόοΫͷडͱͦͷޙͷॲཧΛඇಉظʹ͢Δඞཁ͋Γ • աڈͷϝοηʔδͷΓͱΓͱൺͯฦ৴Λ͍ͨ͠ • → աڈͷΓͱΓΛอଘͯ͠ࢀরͰ͖Δඞཁ͋Γ
εέʔϥϏϦςΟ - Task Queue 13 • ΩϡʔΛͬͯඇಉظʹॲཧ͢Δ • GAE Ͱ
Task Queue ͱ͍͏ػೳ͕ ఏڙ͞Ε͍ͯΔ プロジェクト App Engine App Engine Datastore Instances Search BigQuery Task Queue - GCE - Logs etc. - Networks
εέʔϥϏϦςΟ - Task Queue 14 • Task Queue ͷ Push
Queue Λ͏ • ͖Ίࡉ͔͍࣮ߦ੍ޚ͕؆୯ʹͰ͖Δ • Ұఆ࣌ؒʹॲཧ͢ΔλεΫͷʢྫɿຖඵ100݅ɺຖ࣌50݅ʣ • ಉ࣌ʹॲཧ͢ΔλεΫͷ੍ݶɺࣦഊ࣌ͷ࠶࣮ߦ੍ޚͳͲ • ؆୯ͳઃఆϑΝΠϧʹΩϡʔΛఆٛ͢Δ total_storage_limit: 1T queue: - name: received-messages rate: 100/s RVFVFZBNM
εέʔϥϏϦςΟ - Task Queue 15 • enqueue ͷํ๏ɿλεΫΛ࡞ͬͯΩϡʔʹՃ͢Δ • λεΫʹॲཧઌͱϖΠϩʔυΛࢦఆ
t := taskqueue.NewPOSTTask("/worker/reply-message", url.Values{...}) resultTask, err := taskqueue.Add(ctx, t, "received-message") if err != nil { return err } • dequeue ͷํ๏ɿ • Ωϡʔͷઃఆʹͱ͍ͮͯλεΫ͕ॲཧ͞Ε͍ͯ͘ • ্ͷ߹ POST ϦΫΤετͰ /worker/reply-message ͕ୟ͔ΕΔ • → λεΫ୯७ͳ HTTP ϦΫΤετʹͳΔ
εέʔϥϏϦςΟ - Task Queue 16
εέʔϥϏϦςΟ - ӬଓԽ 17 • ՝ɿաڈͷϝοηʔδͷΓͱΓͱൺͯฦ৴Λ͍ͨ͠ • → աڈͷΓͱΓΛอଘͯ͠ࢀরͰ͖Δඞཁ͋Γ •
NoSQL σʔλϕʔεʮDatastoreʯΛ͏ • ΩʔʹΑΔ CRUD • ෳ߹ΠϯσοΫε • ʢ੍ଟΊͷʣτϥϯβΫγϣϯ • ΫΤϦͳͲ
εέʔϥϏϦςΟ - ӬଓԽ 18 type Message struct { Id int64
SenderId int64 Sender *User `datastore:"-"` Text string Unread bool Location Location CreatedTime time.Time } type Location struct { Lat float64 Lng float64 } • Datastore ʹอଘ͢ΔΤϯςΟςΟΛ ఆٛ͢Δ • ͍ͨͬͯී௨ͷߏମ • datastore λά͕͍͍ͯΔ • อଘ࣌ͷ໊લมߋ • อଘ͢Δ͔Ͳ͏͔ • ୯ҰߦΠϯσοΫεΛ͚Δ͔
εέʔϥϏϦςΟ - ӬଓԽ 19 key := datastore.NewKey(ctx, "Message", "", msg.Id,
nil) if _, err := datastore.Put(ctx, key, msg); err != nil { return err } • ϝοηʔδͷอଘ *% 4FOEFS*E 5FYU 6OSFBE -PDBUJPO-BU -PDBUJPO-OH $SFBUFE5JNF ͜Μʹͪ 536& ͓ෲ͍ͨ͢ '"-4&
εέʔϥϏϦςΟ - ӬଓԽ 20 • ϝοηʔδͷऔಘ key := datastore.NewKey(c, "Message",
"", id, nil) if err := datastore.Get(c, key, &msg); err != nil { return nil, err } q := datastore.NewQuery("Message") q = q.Filter("SenderId =", senderId).Order("-CreatedTime").Limit(10) var msgs []Message _, err := q.GetAll(c, &msgs) • ΫΤϦ
εέʔϥϏϦςΟ - Datastore ͷಛ 21 • Pros • ۃΊͯߴ͍εέʔϥϏϦςΟ •
ӬଓԽͰ͖ΔσʔλʢΤϯςΟςΟʣͷʹ੍ݶͳ͍ • ӬଓԽσʔλ͕ͲΕ͚ͩ૿͑ͯऔಘͱՃͷྼԽ͠ͳ͍ • 1݅Ͱ10ԯ݅Ͱಉ͡ • ಉҰΤϯςΟςΟͰͳ͚Ε੍ݶͳ͠ͷฒྻॻ͖ࠐΈ • ۃΊͯߴ͍Մ༻ੑ • μϯλΠϜͳ͠ • Cons • BigTable ΑΓߴػೳͱ͍͑ϓϦϛςΟϒ • ݶఆ͞Εͨ݅Ͱ͔͠ ACID τϥϯβΫγϣϯ͕αϙʔτ͞Εͳ͍ • JOIN ͕ͳ͍ɺू͕ؔͳ͍ɺetc.
ϩάੳͱӡ༻
ϩάੳͱӡ༻ 23 • Web ΞϓϦΛެ։͢Εɺ ͦͷΞΫηεϩάΛݟͨΓɺ༷ʑͳσʔλੳΛ͢Δඞཁ͋Δ • Web ΞϓϦ͕ਖ਼ৗʹಈ͍͍ͯΔͷ͔Ͳ͏͔ࢹ͍ͨ͠ •
→ ͪΖΜ GAEʢGCPʣ͚ͩͰରԠՄೳ
౷߹͞Ε͍ͯΔϦΞϧλΠϜͷϩάػೳ 24
౷߹͞Ε͍ͯΔϦΞϧλΠϜͷϩάػೳ - τϨʔε 25
౷߹͞Ε͍ͯΔϦΞϧλΠϜͷϩάػೳ - τϨʔε 26
౷߹͞Ε͍ͯΔϦΞϧλΠϜͷϩάػೳ - τϨʔε 27
ϩάੳͱӡ༻ 28 • ϦΫΤετʹͻ͍ͨΞϓϦέʔγϣϯϩάΛग़ྗ͢Δ log.Infof(ctx, "Read Message: id=%v", ids[i])
log.Warningf(ctx, "missing Message entity: id=%v, err=%v", ids[i], err) ͦͷ··ϩάϏϡʔϫʹग़ྗ͞ΕΔ #JH2VFSZͷϦΞϧλΠϜૠೖ ઃఆϘλϯΛԡ͚ͩ͢
ϩάੳͱӡ༻ 29 ϩάͷݕࡧ݅Λࢦఆ ϑΟϧλ໊Λ͚Δ
ϩάੳͱӡ༻ 30 • ࡞ͬͨϩάϑΟϧλΛͬͯɺ ݅Λ࡞ɻ ͖͍͠Λ͑ͨΒΞϥʔτ ʢϝʔϧɺSlack ͳͲ௨ʣ
·ͱΊ 31 1. Google App Engine / Go Ͱ ݱ࣮తͳ
Web ΞϓϦΛ։ൃ͠ɺӡ༻͍ͯ͘͜͠ͱ͕Ͱ͖Δ 2. ͦͯ͠ Go ʹΑΔ Web ΞϓϦ։ൃ͕ɺ ࠓޙ·͢·͋ͨ͢Γ·͑ʹͳ͍ͬͯ͘