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
ワンバイナリWebサービスのススメ
Search
mackee
May 31, 2025
Programming
9k
10
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ワンバイナリWebサービスのススメ
Houtou.pm #1
https://houtoupm.connpass.com/event/348282/
mackee
May 31, 2025
More Decks by mackee
See All by mackee
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
610
perlをWebAssembly上で動かすと何が嬉しいの??? / Where does Perl-on-Wasm actually make sense?
mackee
0
1.1k
Agentに至る道 〜なぜLLMは自動でコードを書けるようになったのか〜
mackee
6
6.1k
今!ソフトウェアエンジニアがハードウェアに手を出すには
mackee
14
7.3k
tanukistack ライブコーディング / tanukistack live-coding
mackee
0
760
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
1.2k
perl for shell, awk and sed programmers
mackee
3
2.9k
今更GoのWebフレームワークを作ろうとしているワケ / Why am I trying to create a Go web framework now?
mackee
1
1.1k
database/sqlでNullを扱う歴史とsql.Null[T]の登場 / sql.Null[T] history
mackee
0
1k
Other Decks in Programming
See All in Programming
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
220
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
170
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
230
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
470
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
450
Jindong: Introducing Declarative Haptics in Compose Multiplatform
l2hyunwoo
0
110
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
140
Flow は今どうなっているか
mizdra
PRO
0
510
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
190
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
330
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
3
770
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
110
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Music & Morning Musume
bryan
47
7.3k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
200
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
170
Test your architecture with Archunit
thirion
1
2.3k
Mobile First: as difficult as doing things right
swwweet
225
10k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Transcript
ϫϯόΠφϦWebαʔϏεͷ εεϝ @mackee_w a.k.a macopy Houtou.pm #1
୭ʁ macopy GitHub: mackee X: mackee_w, mixi2: macopy ໘ന๏ਓΧϠοΫ άϧʔϓใ෦
όοΫΤϯυ, SRE, ΞʔΩςΫτ ද࡞: sqlla(ORM), tanukirpc(WAF)
Kamakura.goͬͯ·͢ʂʂʂ • લճ12݄ • ࣍7݄͔ͳ͋ͱͳͬͯ·͢
͓Βͤ: JRRF2025ʹग़ల͠·͢
ԿͷΛ͢Δͷʁ • αʔϏεΛ1ͭͷόΠφϦʹ·ͱΊͯ1ͭͷαʔόʔʹσϓϩΠ͢Δͷ Ͳ͏͔ͱݴ͏ఏҊ • ରൺ͢ΔͷෳͷΫϥυαʔϏεͰͷߏ(αʔόʔϨε) • ͦΕͧΕϝϦοτɾσϝϦοτ͕͋ΔͷͰ·ͣͦͷհ • ͳͥࠓʮϫϯόΠφϦʯͳͷ͔
͜ͷτʔΫΛ͠Α͏ͱࢥͬͨܦҢ • ීஈαʔόʔϨεߏͰࣄΛ͓ͯ͠Γେมศརʹײ͍ͯ͡Δ • ͔͠͠ؾ͔ͮͳ͍͏ͪʹࣄͷେ͕͍͔ʹखݩͰಈ͍͍ͯΔΞϓϦ έʔγϣϯΛͲ͏αʔόʔϨεߏʹద༻͢Δ͔ͷʹͳ͖ͬͯͨ • ͕࣌ؒͳͯ͘EC2Ͱͦͷ··ཱͯͨΒී௨ʹಈ͍ͨͷͰ͜ΕͰ͍͍ ͡ΌΜͱͳͬͨ
͜ͷηογϣϯͰͷ αʔόʔϨεͱʁ
αʔόʔϨεͷߏཁૉ(1) • FaaS ྫ: AWS Lambda, Cloud fl are Workers,
Cloud Run Functions • αʔόʔཧ͕͍Βͳ͍ • FaaSͷ߹ϦΫΤετॲཧ࣌ؒʹΑΔ՝͕ۚଟ͍ • ϑϧϚωʔδυ or αʔόʔϨεͳDB • RDBMS ͷ߹ϑϧϚωʔδυ͕ଟ͍ ྫ: Amazon RDS, Cloud SQL etc… • NoSQLҰ෦ͷRDBMSαʔόʔϨεత՝ۚϞσϧ ྫ: DynamoDB, Firestore
αʔόʔϨεͷߏཁૉ(2) • ΦϒδΣΫτετϨʔδ ྫ: Amazon S3, Cloud fl are R2,
Cloud Storage • ϑΝΠϧΞοϓϩʔυཁૉ͕͋ΔͱབྷΜͰ͘Δ • KVSͱͯ͠༻͢Δྫ͋Δ • CDN ྫ: Amazon CloudFront, Cloud fl are, Cloud CDN • WebϑϩϯτΤϯυ͕͋ΔαʔϏεͳΒཉ͍͠ • ΤοδͰॲཧͰ͖ͯخ͍͠έʔε͋Δ(CloudFront Functions
αʔόʔϨεͷߏཁૉ(3) • ϝοηʔδΩϡʔ ྫ: Amazon SQS, Cloud fl are Queues,
Cloud Tasks… • ඇಉظͰδϣϒΛΩοΫ͍ͨ͠έʔε͕͋Δ࣌ʹͬͨΓ͢Δ • FaaSͰϨεϙϯεΛฦ͞ͳͯ͘ྑ͍͕͍ॲཧΛΓ͍ͨέʔ εͳͲͰར༻͢Δ • ࣦഊͯ͠ϦτϥΠ͢ΔػߏͳͲ͕ೖͬͯͯخ͍͠
࠷ۙࣄͰ࡞ͬͨߏ
࠷ۙࣄͰ࡞ͬͨߏͦͷ2
झຯͰΔ࣌ͷߏ
ͳͥαʔόʔϨεͰ࡞Δͷ͔ʁ • ѹతʹ͍҆ • ୯७ͳWebαΠτ+গ͔͠Γͷॻ͖ࠐΈΛ͢ΔαΠτΛCDN/FaaS/NoSQL Ͱ࡞͕ͬͨɺͦͦ͜͜ར༻͕͋Δͷʹݸਓͷ͓খݣ͍ఔͰ͍͑ͯΔ • ӡ༻ίετݮ • αʔόʔͷΞοϓσʔτཧ੬ऑੑରԠͳͲͷൣғ͕ڱ͘ͳΔ
• εέʔϧΞτੑೳ • ʮαʔόʔʯ͕མͪΔͱ͍͏͜ͱཧతɾݱ࣮తʹͳ͍
͔͠͠ αʔόʔϨεͩͱࠔΔ͜ͱ͕͋Δ
1. ϩʔΧϧͰ։ൃͨ͠ͷΛͦͷ··͑ͳ͍ • ϩʔΧϧͱαʔόʔϨεڥಉҰͰͳ͍ • ΤϛϡϨʔτखஈ: AWS SAM Local, LocalStack
• ྆ରԠؔϋϯυϥ: fujiwara/ridge • ͦΕͰϓϩηεϞσϧͷҧ͍͔Β͘Δࡉ͔͍ڍಈͷҧ͍, ͦͦ ࣮ݱ͕͍͜͠ͱͳͲ͕͋Δ • ޓϨΠϠʔΛ͍ͭ͘ॻ͘͜ͱʹͳΔ
1. ϩʔΧϧͰ։ൃͨ͠ͷΛͦͷ··͑ͳ͍ • ϩʔΧϧͱαʔόʔϨεڥಉҰͰͳ͍ • ΤϛϡϨʔτखஈ: AWS SAM Local, LocalStack
• ྆ରԠؔϋϯυϥ: fujiwara/ridge • ͦΕͰϓϩηεϞσϧͷҧ͍͔Β͘Δࡉ͔͍ڍಈͷҧ͍, ͦͦ ࣮ݱ͕͍͜͠ͱͳͲ͕͋Δ • ޓϨΠϠʔΛ͍ͭ͘ॻ͘͜ͱʹͳΔ ͩͬͨΒϩʔΧϧͱಉ͡Α͏ͳ ී௨αʔόʔͰྑ͍ͷͰʁ
2. ࣗͷ৫֎Ͱͷӡ༻͕͍͠ • αʔόʔϨεͱ͍͏ΑΓΫϥυͷػೳʹґଘͨ͠αʔϏεͷσϝ Ϧοτ • ͓٬͞Μʮ͏ͪͷΦϯϓϨͰӡ༻͢Δ͔ΒιϑτΣΞΛചͬͯཉ͠ ͍ʯFaaS+αʔόʔϨεDBͰߏஙͨ͠΅͘ʮ…ʯ • 37signalsͷݴ͏ONCEϞσϧαʔόʔϨεલఏͷΞʔΩςΫνϟͩ
ͱࠔʹͳΔ
3. Ͱ͖ͳ͍͜ͱɾ͍͜͠ͱ͕͋Δ • ࠷࣮ۙࡍʹࣄͰͰ͘Θͨ͠՝ • PoCͷΞϓϦέʔγϣϯΛY.jsͱLocalStorageΛΈ߹ΘͤͯΫϥΠΞϯταΠυ͚ͩͰಈ࡞͢ ΔΑ͏ʹ࡞ͬͨ • ࣾͰෳਓͰ͓ࢼ͍͕ͨ͠͠ɺY.jsΛͪΌΜͱωοτϫʔΫܨ͛ͨΓLocalStorageͷσʔλ ຊαʔόʔʹஔ͖͍ͨ
• LambdaͩͱWebSocketΊΜͲ͍͘͞͠ɺ͕࣌ؒͳ͍ͷͰY.jsͷWebSocketαʔόʔΛͦͷ·· ಈ͔͍ͨ͠… • ͍͑ʂ͏EC2ཱͯͯͦ͜ͰWebSocketͷαʔόʔஔ͖·͢ɻAPIαʔόʔαΫοͱॻ͍ͯͦ ͜Ͱϗετ͠·͢ʂ => ͳΜͩ͜ΕͰ͍͍͡ΌΜ
݁ہαʔόʔϨεͰಘΒΕΔͷຊʹඞཁʁ • ίετ • ӡ༻ෛՙͷݮ • εέʔϧΞτੑೳ
• ίετ • (डୗͳͲͷ߹)ίετΑΓఱҪ͕ͳ͍ͱ͍͏ํ͕ྑ͍ͱݴ͏͓٬͞Μ͕͍Δ => ैྔ՝ۚͷ αʔόʔϨε͍ʹ͍͘ • ӡ༻ෛՙͷݮ •
ݱͷಓ۩(ίϯςφorϫϯόΠφϦͰు͘ݴޠ,tailscaleCloud fl are Tunnel, AWS Systems Manager etc…)Λ͑Ͳ͏ʹ͔ͳΔ͔ʁ • εέʔϧΞτੑೳ • ఘΊΔ😇 • CDNͰ͑Δʂαʔόʔ͕མͪͨΒఘΊΔ ݁ہαʔόʔϨεͰಘΒΕΔͷຊʹඞཁʁ
͡Ό͋Ͳ͜ʹσϓϩΠ͢Δʁ • ϩʔΧϧ…࣮༻తͰͳ͍ͷͰ • Cloud fl are TunnelngrokhttpsͰϩʔΧϧͷʹΕͯྑ͍ • https͡Όͳ͍ͱ͑ͳ͍Webٕज़͕͋Δ(ྫ:
Web Push) • ͦ͜ΒลͷదͳVPSʹσϓϩΠ͍ͨ͠ • fl y.ioCloud RunΈ͍ͨͳDocker PaaSͰྑ͍͔ͱࢥ͍·͢ • Ͱී௨ʹσΟεΫʹॻ͍ͯফ͑ͪΌ͏͔Βͳ… • ͱ͍͑ͳΜΒ͔ӬଓతͳσΟεΫΞλονͰ͖Δͱࢥ͍·͢
Ͳ͏ͬͯVPSͰӡ༻͢Δ͔
RailsʹֶͿ • ࠷ۙͷRailsONCEϞσϧ͕Ͱ͖ΔΑ͏ʹSQLiteʹد͍ͤͯΔ • Solid Queue, Solid Cable, Solid Cache
• σϓϩΠπʔϧKamalαʔόʔʹରͯ͠ͷϓϩϏδϣχϯάͱσϓ ϩΠΛߦ͏ • DockerίϯςφͰͷσϓϩΠ • kamal-proxy͕σϓϩΠ࣌ͷϦΫΤετܦ࿏ͷ͚ସ͑Λߦ͏
1ͰΑ͚ΕSQLiteͰྑ͍ • (ࢲSQLite͕ʹ͋ͬͨISUCON12༧બͷ࡞ऀͷҰਓͰ͢) • SQLite༧Ҏ্ͷྲྀྔΛࡹ͘͜ͱ͕Ͱ͖Δ • ϨϓϦέʔγϣϯ͍ͨ͠/ϦετΞ͍ͨ͠ => Litestream
εϥΠυॻ͍ͯͯࢥͬͨ: SQLiteͰGraceful RestartՄೳͳͷʁ • ࣮ݧ: Go + SQLiteͰॻ͍ͨΞϓϦέʔγϣϯʹabͰॻ͖ࠐΈΛܧଓ తʹߦ͍ͭͭɺGraceful Restart
• ͦͦෳͷॻ͖ࠐΈϦΫΤετ͕ಉ࣌ʹདྷΔͱ `database is locked (5) (SQLITE_BUSY)` ͷΑ͏ʹग़ΔͷͰ`sqlite3_busy_timeout` Λઃఆ • `sqlite3_busy_timeout `ͷޮՌͰͳͦ͞͏
࠷ۙͷRailsͰͷSQLiteͷΦϓγϣϯ • `IMMEDIATE` τϥϯβΫγϣϯͷΦϓγϣϯͰɺτϥϯβΫγϣϯΛ ։࢝ͨ࣌͠ʹσʔλϕʔεϩοΫΛऔΔ • WAL(Write Ahead Logging): τϥϯβΫγϣϯͷ୯ҐͰҰ࣌ϑΝΠϧ
Λ࡞ͬͯίϛοτ࣌ʹຊମʹॻ͖ࠐΉ • `sqlite3_busy_timeout` ଞͷεϨου/ϓϩηε͕ϩοΫ͍ͯ͠Δ࣌ʹ ॻ͖ࠐ͏ͱͨ࣌͠ʹԿඵ͔ͭ
GoͰRailsతʹ։ൃ͢Δ • ࠷ۙࣄͰΔ࣌ʹ࠾༻͢ΔελοΫ tanukirpc + sqlla • ϑϩϯτΤϯυTanStack Router +
React + Vite • tanukirpcͱsqllaboilerplateͳίʔυΛgenericsͱίʔυੜͰݮ͢ΔΞ ϓϩʔν • RailsgemͱDSLͰݮ͍ͯ͠Δ • ݸਓతʹ͜ͷΈ߹Θ͕ͤܕ͖ͰϫϯόΠφϦͰు͚ΔRailsͱͯ͠ೝࣝ͠ ͍ͯΔ
͍: ຊʹDocker͕ඞཁͳͷ͔ʁ • RailsͷΑ͏ͳRubyͱଟͷgemͰಈ࡞͢ΔͳΒ͋ͬͨํ͕ྑͦ͞͏ • σϓϩΠͷύοέʔδϯά͕DockerͰ୲͑Δ • gem͕OSଆͷڞ༗ϥΠϒϥϦʹґଘ͍ͯ͠Δέʔε • ෳͷϓϩηεͰಈ͘ͳΒ͋ͬͨํ͕ྑͦ͞͏
GoͷΑ͏ͳϫϯόΠφϦͳΒͲ͏͔ʁ • ϫʔΧʔͱ͔1ͭͷϓϩηεʹ·ͱΊͯgoroutineͰಈ͔ͪ͠Ό͏ • Graceful ShutdownႈੑؤுΖ͏ • σϓϩΠγϯϓϧʹखݩorCIͰϏϧυ => rsync
=> ࠶ىಈͰྑ͍ • ઌ΄ͲͷGraceful RestartͷσϞͰࣔͨ͠server_starterͷྫ
ϑϩϯτΤϯυͲ͏ͬͯΔʁ • `//go:embed` Λ༻͢Δ • ϑΝΠϧσΟϨΫτϦΛؙ͝ͱϓϩάϥϜͷόΠφϦʹ֨ೲ͢Δ • io/fs.FSΠϯλʔϑΣΠεΛ࣮͍ͯ͠ΔͷͰͦͷ··ϑΝΠϧγες ϜͷΑ͏ʹϓϩάϥϜ෦Ͱѻ͑Δ •
embedͰϏϧυͨ͠ϑϩϯτΤϯυΛ֨ೲ͢Δ
ະղܾͷ: σϓϩΠͨ͠Βݹ͍ΞηοτʹΞ ΫηεͰ͖ͳ͘ͳͬͨ • σϓϩΠޙʹϒϥβ͕อ͍࣋ͯ͠Δݹ͍index.htmlͳͲ͕ಡ͏ͱ͍ͯ͠Δݹ͍JSCSSΛಡ ͏ͱͯ͠404ʹͳΔ݅ • kamal-proxyͰղܾͰ͖͍ͯΔ • υΩϡϝϯτΛಡΉͱ྆ํอ͍࣋ͯ͠ΔͬΆ͍ʁ
• ͠Β͘ݹ͍ͭ࣋ͭͷ͕͍͍ΜͰ͠ΐ͏͔ • CloudFront + S3ͰΑ͍ͬͯͨ͘खஈͰ͋Δ͕… • `window.addEventListener(‘error’, …)`Ͱ`location.reload()`͢Δํ๏Ͱ͖ͦ͏ʁ • ͘͠Service Worker?
ͦͷଞͷ: ingress௨৴ • ϙʔτ22൪Λ։͚Δͷ͔ͳΓݏ • tailscaleಥͬࠐΜͰຊsshdΘͣʹTailscaleܦ༝ͰϩάΠϯ͍ͯ͠Δ • ͋ͱufwͰtailscaleҎ֎͔Βͷ֎͔Βͷ௨৴Λશ෦࠹͙ • 443൪։͚ͨ͘ͳ͍
• ͦΜͳ࣌ʹ͑Δͷ͕Cloud fl are Tunnel • cloud fl aredΛཱͯͯɺCloud fl areͰड͚ͨϦΫΤετΛτϯωϧܦ༝Ͱड͚Δ • cloud fl aredegressͷ௨৴͔͠͠ͳ͍ͷͰϙʔτ։͚Δඞཁ͕ͳ͍
͞Βʹͦͷଞ • daemonize • ੲsupervisordͱ͔daemontoolsͱ͔͚͋ͬͨΕͲࠓsystemdͰ͍͍ͱࢥ͏Α • cron • systemdͰ͍͍ͱࢥ͏Α •
ٖࣅcronϫʔΧʔΛgoroutineͰཱͯΔͷ͋Γ • ϩά • systemdͰ͍͍ͱࢥ͏Α • ݕࡧͰू͕ཉ͔ͬͨ͠ΒS3ͱ͔ʹͳΜΒ͔ϩάίϨΫλͰඈ͢ͷ͕͍͍ΜͰ͔͢Ͷ͑ • ࢹ • Mackerelͱ͔NewRelicͱ͔ • ࣗલmisskeyαʔόʔNewRelicೖΕͯΔ • ϓϩϏδϣχϯά • mitamae͔ͳ͋ systemdͷunitϑΝΠϧΛಥͬࠐΉͷࣗ࡞͔ͯ͑͑͠͠ΕΜ
Ҏ্ GoͰϫϯόΠφϦ+SQLiteͰαʔϏε ߏஙͷͰͨ͠