Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Goとコンテナで作るWebアプリケーションベンチマーカー / Benchmarker buil...
Search
FUJIWARA Shunichiro
June 30, 2018
Technology
5.5k
9
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Goとコンテナで作るWebアプリケーションベンチマーカー / Benchmarker built with Go and Container
FUJIWARA Shunichiro
June 30, 2018
More Decks by FUJIWARA Shunichiro
See All by FUJIWARA Shunichiro
多摩川(.dev)ランニング入門 / Tamagawa.dev#3
fujiwara3
3
530
クラウドを使う側から、作る側へ / 大吉祥寺.pm 2026前夜祭
fujiwara3
8
2.2k
作るべきものと向き合う - ecspresso 8年間の開発史から学ぶ技術選定 / 技術選定con findy 2026
fujiwara3
9
6.1k
さくらのクラウドでのシークレット管理を考える/tamachi.sre#2
fujiwara3
2
400
Amazon ECS デプロイツール ecspresso の開発を支える「正しい抽象化」の探求 / YAPC::Fukuoka 2025
fujiwara3
13
14k
パフォーマンスチューニングのために普段からできること/Performance Tuning: Daily Practices
fujiwara3
9
6.9k
alecthomas/kong はいいぞ
fujiwara3
7
2.6k
ecspressoの設計思想に至る道 / sekkeinight2025
fujiwara3
12
3.8k
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
4
5.6k
Other Decks in Technology
See All in Technology
SREは、MCPとAutopilotをこう使え!
kazumax55
3
890
Azure Serverless 2026:Production-ready な AI エージェント基盤 / Azure Serverless 2026: Production-Ready AI Agent Platform
miyake
2
220
積み重なった技術負債への挑戦 〜初手としての全社ゴト化〜
techtekt
PRO
0
1.3k
Claude in Chrome 入門 / Introduction to Claude in Chrome
cielo1985
0
860
Cloudflare Workers 向けアプリを C# で構築する ~WASM Native AOT への道~
nenonaninu
1
330
AIは推し活である。
kurazuuuuuu
1
360
山手線を徒歩で一周してわかった、 位置情報アプリは「足」が最強のデバッガー
hinakko
0
160
AgentCore Runtime上にAgentic Coding基盤を構築・展開する際の設計ポイントと限界点 / Design considerations and limitations when building an agentic coding platform on AgentCore Runtime
har1101
4
310
aws-iot-platform-architecture-use-cases.pdf
ma2shita
0
310
AI に書かせたその API、 “信頼” できますか?
nagix
0
120
10Xに技術的負債をもたらした「2つの境界の歪み」その構造と解消への営み
10xinc
0
2.1k
2026-09-18 gotanda.sre Terraformで複数環境作ったり、複数Stateに分割したりそれとTerragrunt / Terraform multi envs and multi states
masasuzu
2
520
Featured
See All Featured
Side Projects
sachag
456
43k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
420
How GitHub (no longer) Works
holman
316
150k
How to build a perfect <img>
jonoalderson
1
6k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Un-Boring Meetings
codingconduct
0
420
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
390
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
A Soul's Torment
seathinner
8
3.6k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
Rails Girls Zürich Keynote
gr2m
96
14k
Transcript
Hackers Champloo 2018 GoͱίϯςφͰ࡞Δ WebΞϓϦέʔγϣϯ ϕϯνϚʔΧʔ 2018.06.30 @fujiwara
@fujiwara ٕज़෦ github.com/fujiwara sfujiwara.hatenablog.com ISUCON 8 ग़νʔϜ
Game & Community
None
Γ͍ͨ͜ͱ Perl / Go + WebSocket Ͱߏ͞Εͨ ήʔϜαʔόʹରͯ͠ ϕϯνϚʔΫΛֻ͚͍ͨ
ͳͥΔͷ͔ - ੑೳධՁ / ݶքଌఆ • XXXϢʔβ·ͰͷΞΫηεʹ͑ΒΕΔ͔ • ඪϢʔβʹ͑ΒΕͳ͍ =
͓ۚʹͳΒͳ͍ • ΠϯελϯεαΠζɺ = ͓͍ۚ͘Β͔͔Δͷ͔ • ίετֻ͕͔Γ͍͚͗ͯ͢ͳ͍ • ϨεϙϯελΠϜ • ϢʔβʹշదͳମݧΛͯ͠Β͑Δ͔
ͳͥΔͷ͔ - ຊ൪ϦϦʔεͷ४උ ΞϓϦέʔγϣϯ / ϛυϧΣΞͷෆඋΛચ͍ग़͢ • ϘτϧωοΫݕग़ • DB
ͷ index ͕ͳ͍ͱ͔ • ֤छઃఆ͕ద͔ • failover ਖ਼ৗʹಈ࡞͢Δ͔
ͳͥΔͷ͔ - ຊ൪ϦϦʔεͷ४උ ϞχλϦϯά͕ద͔Λચ͍ग़͢ • ΄͍͠ϝτϦΫε͕ऩूͰ͖͍ͯΔ͔ • ݟ͍ͨάϥϑ͕͙͢ݟΒΕΔ͔ • ϘτϧωοΫ͕దʹݕͰ͖Δ͔
• ΞϥʔτͷᮢΛܾΊΔ
۩ମతʹΓ͍ͨ͜ͱ REST API Λୟ͍ͯͦͷ݁ՌΛͬͯ࣍ͷϦΫΤετ • ྫ / → /signup →
/login → /mypage → /infomation ೝূ͕ಠࣗ • CookieͰͳ͍ HTTP ϦΫΤετϔομʹ token • ຖճ unique ͳΛૹ৴ɺ࠶ૹʹΑΔଟॏϦΫΤετݕ • Challenge & Response • ϦϓϨΠ߈ܸͳͲΛ͙
۩ମతʹΓ͍ͨ͜ͱ ήʔϜͷਐߦʹ WebSocket ͕ΘΕ͍ͯΔ • ଞͷϢʔβ͕ൃੜͤͨ͞Πϕϯτ͕ WebSocket Ͱ߱ͬͯ͘ Δ •
Payload MessagePack • ͦͷΠϕϯτʹΑͬͯϦΫΤετΛม͑Δඞཁ͕͋Δ
ͳʹͰΔͷ͔ طʹੈʹ͋Δෛՙࢼݧπʔϧ ApacheBench (ab) • Apache HTTPd ʹଐ • 1
URL ʹͻͨ͢ΒϦΫΤετ͢Δ $ ab -c 10 -n 1000 http://example.com/
ͳʹͰΔͷ͔ wrk github.com/wg/wrk • ApachBench ΑΓߴػೳ $ wrk -c 10
-d 3 http://example.com/
wrk - ϦΫΤετΛ Lua ͰΧελϚΠζ wrk.method = "POST" wrk.body =
"foo=bar&baz=quux" wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
ͬͱߴػೳͳπʔϧ Apache JMeter - jmeter.apache.org • Java • GUI ͕͋Δ
• γφϦΦ GUI or XML (jmx)
Gatling - gatling.io • Scalar • γφϦΦ Scala Ͱهड़
JMeter or Gatling ? ͲͪΒ • WebSocket ͕ѻ͑Δ • JMeterϓϥάΠϯ
• γφϦΦϨίʔμʔ͕͋Δ • HTTP Proxy ͱͯ͠ಈ࡞ͯ͠ϒϥβૢ࡞Λ capture ͢Δ
Go Ͱࣗ࡞͢Δ ձࣾͷڞ௨ݴޠ͕ Go / Perl / Ruby (ಛʹαʔό͕ Go
ͷ߹) • JSON API / WebSocket Payload ͷߏମ͕ڞ௨ʹͰ͖Δ Ϩϙʔτ͕͖Ε͍Ͱ͋Δඞཁͳ͍ • αʔόଆͷϞχλϦϯάͰ࣮ݱ͞Ε͍ͯΔඞཁ͕͋Δ • req/sec, εςʔλείʔυͷׂ߹ ϨεϙϯελΠϜ
ͲͷΑ͏ʹ࡞Δ͔
ΞʔΩςΫνϟ
ϕϯνϚʔΫΫϥΠΞϯτ net/http.Client, gorilla/websocket.Dialer Λ࣋ͭ type Client struct { client *http.Client
wsDialer *websocket.Dialer // ... }
γφϦΦΛ͋ΒΘ͢ struct Client Λ࣋ͭ type Scenario struct { client *bench.Client
// ... }
࣮ࡍͷϕϯνϚʔΫࢼߦ func (s *Scenario) Run(ctx context.Context) (score int64) { //
websocketܨ͙ conn, _, _ := s.client.ConnectWebsocket() defer conn.Close() // room ೖࣨ res, _ := s.client.Post("/api/room/join") EVENT: for { _, b, err := conn.ReadMessage() ev, _ := event.Decode(b) switch ev := ev.(type) { case event.RoomJoinEvent: // ...
γφϦΦΛ࠷େNฒྻͰಈ͔͢ channel Λͬͨ semaphore ύλʔϯ func Run() { sem :=
make(chan struct{}, 100) // ࠷େ100ฒྻ for { sem <- struct{}{}: // 100 Ҏ্ʹͳΒͳ͍Α͏ʹηϚϑΥऔಘ go func() { sc := newScenario() // γφϦΦੜ defer func() { <-sem // ऴΘͬͨͱ͜ΖͰηϚϑΥ։์ }() sc.Run() // ϕϯνϚʔΫ }() time.Sleep(spawnInterval) // ࣍ͷγφϦΦੜͪΐͬͱͭ } }
sem := make(chan struct{}, 4) // □□□□ // main scenario
sem <- struct{}{} ▪□□□ // (1) sem <- struct{}{} ▪▪□□ // (2) sem <- struct{}{} ▪▪▪□ // (3) sem <- struct{}{} ▪▪▪▪ // (4) sem <- struct{}{} ▪▪▪▪◆ // (5) ▪▪▪□ <- sem // (1) ▪▪▪▪ // (5) sem <- struct{}{} ▪▪▪▪◆ // (6) ▪▪▪□ <- sem // (2) ▪▪▪▪ // (6)
࣮Ͱҙ͢Δ͜ͱ
Ұؾʹىಈ͠ͳ͍ 1msֻ͔͔͠Βͳ͍ϦΫΤετΛ1ඵ͝ͱʹ࣮ߦ͢ΔγφϦΦΛ × 1000ฒྻͰ࣮ߦ͠ଓ͚Δ߹ Ұؾʹىಈ͢Δͱຖඵ࠷ॳͷmsʹෛՙ͕ूத͢Δ ࣮ࡍͷϢʔβͷϦΫΤετঢ়گͱҟͳΔ (…ͱݶΒͳ͍͚Ͳ)
దʹ(ࢄͯ͠) Sleep ͢Δ ͖ͬͪΓ 100ms ͣͭͣΒͯ͠͠·͏ͱ ຖඵ 0, 100, 200,
... 900 ms ͷλΠϛϯάʹෛՙ͕ूத͢Δ దʹฏۉ100msͰࢄ͢ΔΛٻΊΔʹ…?
Go Ͱਖ਼نཚΛٻΊΔ - math/rand func NormFloat64() float64 returns a normally
distributed float64 in the range [-math.MaxFloat64, +math.MaxFloat64] with standard normal distribution (mean = 0, stddev = 1) sample = NormFloat64() * desiredStdDev + desiredMean
rand.NormFloat64()*4 + 10 0 ########## 1 ############## 2 ############# 3
############################ 4 ######################################## 5 ######################################################## 6 ############################################################## 7 ################################################################################### 8 ############################################################################################### 9 ############################################################################################## 10 ############################################################################################################ 11 ############################################################################################## 12 ################################################################################## 13 ###################################################################### 14 ############################################## 15 ######################################## 16 ##################### 17 #################### 18 ######### 19 #####
net/http.Get() ΛΘͳ͍ resp, err := http.Get("http://example.com/") ҉ʹ http.DefaultClient ͕ΘΕΔ •
ಉҰϗετͷϦΫΤετΛ KeepAlive ͍ͯ͠ΔίωΫγϣ ϯʹ·ͱΊͯ͠·͏ͷͰίωΫγϣϯ͕ݮΔ • ࣮ࡍʹϢʔβͷ͕ͦΕͧΕଓΛுΔঢ়گͷγϛϡϨʔ γϣϯʹͳΒͳ͍
͏͔ͬΓ HTTP/2 ʹҙ AWS ALB σϑΥϧτͰ HTTP/2 ରԠ͍ͯ͠Δ net/http.Client σϑΥϧτͰ
HTTP/2 Ͱܨ͛ΔͳΒܨ͙ ࣮ࡍͷΫϥΠΞϯτ͕ HTTP/1 ͷ߹ͷ γϛϡϨʔγϣϯʹͳΒͳ͍ ࣮ߦ࣌ʹڥม GODEBUG=http2client=0 ͰແޮԽͰ͖Δ ৄ͘͠ godoc.org/net/http
ଓΛͪΌΜͱෳுΔ http.Client Λผʹ༻ҙͨ͠߹ c := &http.Client{} req, _ := http.NewRequest("GET",
"https://example.com/", nil) resp, err := c.Do(req) //... • http1 ͳΒͦΕͧΕͷΫϥΠΞϯτ͕ผͷTCPଓΛ࣋ͭ • http2 ͩͱͻͱͭͷίωΫγϣϯΛ͍ճ͢(!!)
http.Transport Λผʑʹ࡞Ε h2 Ͱผଓ c := &http.Client{ Transport: &http.Transport{}, }
req, _ := http.NewRequest("GET", "https://example.com/", nil) resp, err := c.Do(req) //...
ϢʔβͷΞΫηεΛͨ͠ϕϯνϚʔΫʹ͢Δ ؾͮͨ͘Ίʹ • αʔόଆͷίωΫγϣϯΛϞχλϦϯά͢Δ • ΞΫηεϩάʹΫϥΠΞϯτͷ IP ΞυϨε͚ͩͰͳ͘ɺ port ग़ྗ͢Δ
• ಉҰ port ͕͍ճ͞Ε͍ͯΔ༷ࢠ͕͔Δ ϕϯνϚʔΫΛਖ਼֬ʹ͢Δ = ϞχλϦϯάେࣄ
࣮ࡍͷϢʔβϕϯνϚʔΫΛ࣮ߦ͢Δ 1ϓϩηε/ϗετ͔ΒଓͰ͖Δྔʹ੍͕͋Δ ͨͱ͑10ສಉ࣌Ϣʔβͷ݁Ռ͕΄͍͠ͱͯ͠ • CPU (32ίΞͩͱͯ͠ 0.00032 core/user ͔͑͠ͳ͍) •
Memory (1MB * 10ສ = 100GB) • ଳҬ (100Kbps * 10ສ= 10 Gbps) • IP source port (16bit = 65535 Ͳ͏ؤுͬͯແཧ) ෳʹࢄ͢Δඞཁ͕͋Δ
Amazon ECS Ͱ ϕϯνϚʔΫΛେྔ࣮ߦ
ϕϯνϚʔΫ༻ͷ ECS Ϋϥελ(EC2 Πϯελϯεͷଋ) Λ༻ҙ ͦ͜ʹλεΫ(ίϯςφ্Ͱಈ͘ϓϩηε)Λෳ࣮ߦ
ϕϯνΫϥΠΞϯτଆͷϝτϦΫεΛͲ͏औΔ͔ 1ϓϩηεͰ͋Ε 1000ฒྻͰ࣮ߦ = 1000ฒྻ࣌ͷෛՙ ෳϓϩηεΛঃʑʹىಈͯ͠ɺঃʑʹෛՙΛ্͍͛ͯ͘߹ ݱࡏԿฒྻͰಈ͍ͯΔ? ͔ΛՄࢹԽ͢Δඞཁ͕͋Δ e.g. 1,000
→ 10,000ฒྻ·Ͱͳ͠ɺ12,000ʹͨ͠Β XXX ͕ աෛՙʹͳͬͯΤϥʔൃੜɺͳͲΛه͍ͨ͠
None
Amazon CloudWatch ͰΧελϜϝτϦΫεΛه͢Δ ϦιʔεͷϞχλϦϯάͷͨΊͷϚωʔδυαʔϏε AWS Ͱಈ࡞͍ͯ͠ΔαʔϏεɺίϯϙʔωϯτͷϝτϦΫε͕ େ͜͜ʹه͞Ε͍ͯΔ EC2 CPU, ELB
Request, RDS... ଞ͋ΒΏΔͷ
ΧελϜϝτϦΫεͷσʔλߏ Namespace: benchmark # ໊લۭؒ MetricName: Concurrency # ϝτϦοΫ໊ Value:
1000 # (float) Timestamp: 1528075230 # ࣌ࠁ(UNIX time) Dimensions: - Name: Scenario Value: GvG
Dimensions? σʔλͷूܭͷͨΊͷϝλσʔλ ಉ࣌ؒ͡(ଳ)ʹొ͞Εͨෳͷʹରͯ͠ Dimension ͝ͱʹ ߹ܭ, ࠷େ, ࠷খ, Percentile, σʔλݸ
Λूܭͨ݁͠ՌΛऔಘͰ͖Δ
ͳͥ CloudWatch ͕ίϯςφڥͷϝτϦΫε ूܭʹ͍͍ͯΔ͔ ίϯςφಉ࣌ʹ͍࣮ͭ͘ߦ͞ΕΔ͔͔Βͳ͍ ͦΕͧΕͷίϯςφ͓ޓ͍ͷ͜ͱΒͳ͍ ࣗࣗͷϝτϦΫεΛ CloudWatch ʹ͛Δ CloudWatch
ಉҰ࣌ࠁ ಉҰ Dimension ͷΛूܭͰ͖Δ ϝτϦΫε͕͍ͭ͋ͬͯؔ͘ͳ͍
ҙຯͷ͋ΔूܭΛ͢Δ ͲͷΑ͏ʹूܭ͢ΔͱΞϓϦέʔγϣϯతʹ ҙຯͷ͋Δ͕ಘΒΕΔ͔ਓ͕ؒߟ͑Δඞཁ͕͋Δ • ϦΫΤετɺಉ࣌ଓ = ߹ܭ • ϨΠςϯγ =
ฏۉɺPercentile
https://2018.cedec.cesa.or.jp/session/108 2018.08.22 (ਫ) - 08.24 (ۚ) ύγϑΟίԣ
ΦϯϥΠϯ༧બ 9݄15(),16() ຊબ 10݄20() ༏উۚ100ສԁ ֶੜɺ͓Ұਓ༷ࢀՃ͋Γ
None