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
570
クラウドを使う側から、作る側へ / 大吉祥寺.pm 2026前夜祭
fujiwara3
8
2.2k
作るべきものと向き合う - ecspresso 8年間の開発史から学ぶ技術選定 / 技術選定con findy 2026
fujiwara3
9
6.2k
さくらのクラウドでのシークレット管理を考える/tamachi.sre#2
fujiwara3
2
420
Amazon ECS デプロイツール ecspresso の開発を支える「正しい抽象化」の探求 / YAPC::Fukuoka 2025
fujiwara3
13
14k
パフォーマンスチューニングのために普段からできること/Performance Tuning: Daily Practices
fujiwara3
9
7k
alecthomas/kong はいいぞ
fujiwara3
7
2.6k
ecspressoの設計思想に至る道 / sekkeinight2025
fujiwara3
12
3.8k
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
4
5.7k
Other Decks in Technology
See All in Technology
UniFi(ユニファイ)AIカメラの現場活用
ludicmind
1
300
オブザーバビリティを高める AI エージェント体験を考える / Designing AI Agent Experiences That Enhance Observability
aoto
PRO
2
320
全PRの83%が AIレビューだけでマージできるようになった開発組織は その後どうなったか @2026/10
athug
0
130
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
830
プロダクト価値を、 チームが使える判断軸に変える
vivion
0
140
無理せず続ける、子育てエンジニアの学び
codmoninc
PRO
0
490
継続的なAIコスト最適化
bgpat
1
250
AgentCoreで実践するハーネスエンジニアリング
yakumo
1
290
ビジネスを止めない技術的負債の返済のための戦略とその手法 - 技術的負債と向き合う / Complexity and Simplicity
soudai
PRO
3
670
freeeらしさをAIとともに作る / Creating the freee Experience with AI
ymrl
0
210
AI 時代の Azure エンジニアリング ~ 私たちは何を磨き、何を任せるのか ~
chack411
1
540
Execution in the Kingdom of Agents: Reflections on Abstraction and Complexity
bcantrill
0
880
Featured
See All Featured
Darren the Foodie - Storyboard
khoart
PRO
4
4k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
580
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Color Theory Basics | Prateek | Gurzu
gurzu
1
480
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
260
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
270
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
4
4.3k
Believing is Seeing
oripsolob
1
240
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
910
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
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