Slide 1

Slide 1 text

ϫϯόΠφϦWebαʔϏεͷ εεϝ @mackee_w a.k.a macopy Houtou.pm #1

Slide 2

Slide 2 text

୭ʁ macopy GitHub: mackee X: mackee_w, mixi2: macopy ໘ന๏ਓΧϠοΫ άϧʔϓ৘ใ෦ όοΫΤϯυ, SRE, ΞʔΩςΫτ ୅ද࡞: sqlla(ORM), tanukirpc(WAF)

Slide 3

Slide 3 text

Kamakura.go΍ͬͯ·͢ʂʂʂ • લճ͸12݄ • ࣍͸7݄͔ͳ͋ͱͳͬͯ·͢

Slide 4

Slide 4 text

͓஌Βͤ: JRRF2025ʹग़ల͠·͢

Slide 5

Slide 5 text

Կͷ࿩Λ͢Δͷʁ • αʔϏεΛ1ͭͷόΠφϦʹ·ͱΊͯ1ͭͷαʔόʔʹσϓϩΠ͢Δͷ ͸Ͳ͏͔ͱݴ͏ఏҊ • ରൺ͢Δͷ͸ෳ਺ͷΫϥ΢υαʔϏεͰͷߏ੒(αʔόʔϨε) • ͦΕͧΕϝϦοτɾσϝϦοτ͕͋ΔͷͰ·ͣͦͷ঺հ • ͳͥࠓʮϫϯόΠφϦʯͳͷ͔

Slide 6

Slide 6 text

͜ͷτʔΫΛ͠Α͏ͱࢥͬͨܦҢ • ීஈ͸αʔόʔϨεߏ੒Ͱ࢓ࣄΛ͓ͯ͠Γେมศརʹײ͍ͯ͡Δ • ͔͠͠ؾ͔ͮͳ͍͏ͪʹ࢓ࣄͷେ൒͕͍͔ʹखݩͰಈ͍͍ͯΔΞϓϦ έʔγϣϯΛͲ͏αʔόʔϨεߏ੒ʹద༻͢Δ͔ͷ࿩ʹͳ͖ͬͯͨ • ͕࣌ؒͳͯ͘EC2Ͱͦͷ··ཱͯͨΒී௨ʹಈ͍ͨͷͰ͜ΕͰ͍͍ ͡ΌΜͱͳͬͨ

Slide 7

Slide 7 text

͜ͷηογϣϯͰͷ αʔόʔϨεͱ͸ʁ

Slide 8

Slide 8 text

αʔόʔϨεͷߏ੒ཁૉ(1) • FaaS ྫ: AWS Lambda, Cloud fl are Workers, Cloud Run Functions • αʔόʔ؅ཧ͕͍Βͳ͍ • FaaSͷ৔߹͸ϦΫΤετ΍ॲཧ࣌ؒʹΑΔ՝͕ۚଟ͍ • ϑϧϚωʔδυ or αʔόʔϨεͳDB • RDBMS ͷ৔߹͸ϑϧϚωʔδυ͕ଟ͍ ྫ: Amazon RDS, Cloud SQL etc… • NoSQL΍Ұ෦ͷRDBMS͸αʔόʔϨεత՝ۚϞσϧ ྫ: DynamoDB, Firestore

Slide 9

Slide 9 text

αʔόʔϨεͷߏ੒ཁૉ(2) • ΦϒδΣΫτετϨʔδ ྫ: Amazon S3, Cloud fl are R2, Cloud Storage • ϑΝΠϧΞοϓϩʔυཁૉ͕͋ΔͱབྷΜͰ͘Δ • KVSͱͯ͠୅༻͢Δྫ΋͋Δ • CDN ྫ: Amazon CloudFront, Cloud fl are, Cloud CDN • WebϑϩϯτΤϯυ͕͋ΔαʔϏεͳΒཉ͍͠ • ΤοδͰॲཧͰ͖ͯخ͍͠έʔε΋͋Δ(CloudFront Functions౳

Slide 10

Slide 10 text

αʔόʔϨεͷߏ੒ཁૉ(3) • ϝοηʔδΩϡʔ ྫ: Amazon SQS, Cloud fl are Queues, Cloud Tasks… • ඇಉظͰδϣϒΛΩοΫ͍ͨ͠έʔε͕͋Δ࣌ʹ࢖ͬͨΓ͢Δ • FaaSͰϨεϙϯεΛฦ͞ͳͯ͘΋ྑ͍͕௕͍ॲཧΛ΍Γ͍ͨέʔ εͳͲͰར༻͢Δ • ࣦഊͯ͠΋ϦτϥΠ͢ΔػߏͳͲ͕ೖͬͯͯخ͍͠

Slide 11

Slide 11 text

࠷ۙ࢓ࣄͰ࡞ͬͨߏ੒

Slide 12

Slide 12 text

࠷ۙ࢓ࣄͰ࡞ͬͨߏ੒ͦͷ2

Slide 13

Slide 13 text

झຯͰ΍Δ࣌ͷߏ੒

Slide 14

Slide 14 text

ͳͥαʔόʔϨεͰ࡞Δͷ͔ʁ • ѹ౗తʹ͍҆ • ୯७ͳWebαΠτ+গ͠͹͔Γͷॻ͖ࠐΈΛ͢ΔαΠτΛCDN/FaaS/NoSQL Ͱ࡞͕ͬͨɺͦͦ͜͜ར༻͕͋Δͷʹݸਓͷ͓খݣ͍ఔ౓Ͱ࿫͍͑ͯΔ • ӡ༻ίετ௿ݮ • αʔόʔͷΞοϓσʔτ؅ཧ΍੬ऑੑରԠͳͲͷൣғ͕ڱ͘ͳΔ • εέʔϧΞ΢τੑೳ • ʮαʔόʔʯ͕མͪΔͱ͍͏͜ͱ͸ཧ࿦తɾݱ࣮తʹ͸ͳ͍

Slide 15

Slide 15 text

͔͠͠ αʔόʔϨεͩͱࠔΔ͜ͱ͕͋Δ

Slide 16

Slide 16 text

1. ϩʔΧϧͰ։ൃͨ͠΋ͷΛͦͷ··࢖͑ͳ͍ • ϩʔΧϧͱαʔόʔϨε؀ڥ͸ಉҰͰ͸ͳ͍ • ΤϛϡϨʔτखஈ: AWS SAM Local, LocalStack౳ • ྆ରԠؔ਺ϋϯυϥ: fujiwara/ridge౳ • ͦΕͰ΋ϓϩηεϞσϧͷҧ͍͔Β͘Δࡉ͔͍ڍಈͷҧ͍, ͦ΋ͦ΋ ࣮ݱ͕೉͍͜͠ͱͳͲ͕͋Δ • ޓ׵ϨΠϠʔΛ͍ͭ͘΋ॻ͘͜ͱʹͳΔ

Slide 17

Slide 17 text

1. ϩʔΧϧͰ։ൃͨ͠΋ͷΛͦͷ··࢖͑ͳ͍ • ϩʔΧϧͱαʔόʔϨε؀ڥ͸ಉҰͰ͸ͳ͍ • ΤϛϡϨʔτखஈ: AWS SAM Local, LocalStack౳ • ྆ରԠؔ਺ϋϯυϥ: fujiwara/ridge౳ • ͦΕͰ΋ϓϩηεϞσϧͷҧ͍͔Β͘Δࡉ͔͍ڍಈͷҧ͍, ͦ΋ͦ΋ ࣮ݱ͕೉͍͜͠ͱͳͲ͕͋Δ • ޓ׵ϨΠϠʔΛ͍ͭ͘΋ॻ͘͜ͱʹͳΔ ͩͬͨΒϩʔΧϧͱಉ͡Α͏ͳ ී௨αʔόʔͰྑ͍ͷͰ͸ʁ

Slide 18

Slide 18 text

2. ࣗ෼ͷ૊৫֎Ͱͷӡ༻͕೉͍͠ • αʔόʔϨεͱ͍͏ΑΓΫϥ΢υͷػೳʹґଘͨ͠αʔϏεͷσϝ Ϧοτ • ͓٬͞Μʮ͏ͪͷΦϯϓϨͰӡ༻͢Δ͔Βιϑτ΢ΣΞΛചͬͯཉ͠ ͍ʯFaaS+αʔόʔϨεDBͰߏஙͨ͠΅͘ʮ…ʯ • 37signalsͷݴ͏ONCEϞσϧ͸αʔόʔϨεલఏͷΞʔΩςΫνϟͩ ͱࠔ೉ʹͳΔ

Slide 19

Slide 19 text

3. Ͱ͖ͳ͍͜ͱɾ೉͍͜͠ͱ͕͋Δ • ࠷࣮ۙࡍʹ࢓ࣄͰͰ͘Θͨ͠՝୊ • PoCͷΞϓϦέʔγϣϯΛY.jsͱLocalStorageΛ૊Έ߹ΘͤͯΫϥΠΞϯταΠυ͚ͩͰಈ࡞͢ ΔΑ͏ʹ࡞ͬͨ • ࣾ಺Ͱෳ਺ਓͰ͓ࢼ͍͕ͨ͠͠ɺY.jsΛͪΌΜͱωοτϫʔΫܨ͛ͨΓLocalStorage಺ͷσʔλ ͸ຊ౰͸αʔόʔʹஔ͖͍ͨ • LambdaͩͱWebSocketΊΜͲ͍͘͞͠ɺ͕࣌ؒͳ͍ͷͰY.jsͷWebSocketαʔόʔΛͦͷ·· ಈ͔͍ͨ͠… • ͍͑ʂ΋͏EC2ཱͯͯͦ͜ͰWebSocketͷαʔόʔஔ͖·͢ɻAPIαʔόʔ΋αΫοͱॻ͍ͯͦ ͜Ͱϗετ͠·͢ʂ => ͳΜͩ͜ΕͰ͍͍͡ΌΜ

Slide 20

Slide 20 text

݁ہαʔόʔϨεͰಘΒΕΔ΋ͷ͸ຊ౰ʹඞཁʁ • ௿ίετ • ӡ༻ෛՙͷ௿ݮ • εέʔϧΞ΢τੑೳ

Slide 21

Slide 21 text

• ௿ίετ • (डୗͳͲͷ৔߹͸)௿ίετΑΓఱҪ͕ͳ͍ͱ͍͏ํ͕ྑ͍ͱݴ͏͓٬͞Μ͕͍Δ => ैྔ՝ۚͷ αʔόʔϨε͸࢖͍ʹ͍͘ • ӡ༻ෛՙͷ௿ݮ • ݱ୅ͷಓ۩(ίϯςφorϫϯόΠφϦͰు͘ݴޠ,tailscale΍Cloud fl are Tunnel, AWS Systems Manager etc…)Λ࢖͑͹Ͳ͏ʹ͔ͳΔ͔΋ʁ • εέʔϧΞ΢τੑೳ • ఘΊΔ😇 • CDNͰ଱͑Δʂαʔόʔ͕མͪͨΒఘΊΔ ݁ہαʔόʔϨεͰಘΒΕΔ΋ͷ͸ຊ౰ʹඞཁʁ

Slide 22

Slide 22 text

͡Ό͋Ͳ͜ʹσϓϩΠ͢Δʁ • ϩʔΧϧ…͸࣮༻తͰ͸ͳ͍ͷͰ • Cloud fl are Tunnel΍ngrok͸httpsͰϩʔΧϧͷʹ΋஻Εͯྑ͍ • https͡Όͳ͍ͱ࢖͑ͳ͍Webٕज़͕͋Δ(ྫ: Web Push) • ͦ͜Βลͷద౰ͳVPSʹσϓϩΠ͍ͨ͠ • fl y.io΍Cloud RunΈ͍ͨͳDocker PaaSͰ΋ྑ͍͔ͱࢥ͍·͢ • Ͱ΋ී௨ʹσΟεΫʹॻ͍ͯ΋ফ͑ͪΌ͏͔Βͳ… • ͱ͸͍͑ͳΜΒ͔ӬଓతͳσΟεΫ͸Ξλον͸Ͱ͖Δͱ͸ࢥ͍·͢

Slide 23

Slide 23 text

Ͳ͏΍ͬͯVPSͰӡ༻͢Δ͔

Slide 24

Slide 24 text

RailsʹֶͿ • ࠷ۙͷRails͸ONCEϞσϧ͕Ͱ͖ΔΑ͏ʹSQLiteʹد͍ͤͯΔ • Solid Queue, Solid Cable, Solid Cache • σϓϩΠπʔϧKamal͸αʔόʔʹରͯ͠ͷϓϩϏδϣχϯάͱσϓ ϩΠΛߦ͏ • DockerίϯςφͰͷσϓϩΠ • kamal-proxy͕σϓϩΠ࣌ͷϦΫΤετܦ࿏ͷ෇͚ସ͑Λߦ͏

Slide 25

Slide 25 text

1୆ͰΑ͚Ε͹SQLiteͰྑ͍ • (ࢲ͸SQLite͕໰୊ʹ͋ͬͨISUCON12༧બͷ໰୊࡞ऀͷҰਓͰ͢) • SQLite͸༧૝Ҏ্ͷྲྀྔΛࡹ͘͜ͱ͕Ͱ͖Δ • ϨϓϦέʔγϣϯ͍ͨ͠/ϦετΞ͍ͨ͠ => Litestream

Slide 26

Slide 26 text

εϥΠυॻ͍ͯͯࢥͬͨ: SQLiteͰGraceful RestartՄೳͳͷʁ • ࣮ݧ: Go + SQLiteͰॻ͍ͨΞϓϦέʔγϣϯʹabͰॻ͖ࠐΈΛܧଓ తʹߦ͍ͭͭɺGraceful Restart • ͦ΋ͦ΋ෳ਺ͷॻ͖ࠐΈϦΫΤετ͕ಉ࣌ʹདྷΔͱ `database is locked (5) (SQLITE_BUSY)` ͷΑ͏ʹग़ΔͷͰ`sqlite3_busy_timeout` Λઃఆ • `sqlite3_busy_timeout `ͷޮՌͰ໰୊ͳͦ͞͏

Slide 27

Slide 27 text

࠷ۙͷRailsͰͷSQLiteͷΦϓγϣϯ • `IMMEDIATE` τϥϯβΫγϣϯͷΦϓγϣϯͰɺτϥϯβΫγϣϯΛ ։࢝ͨ࣌͠ʹσʔλϕʔεϩοΫΛऔΔ • WAL(Write Ahead Logging): τϥϯβΫγϣϯͷ୯ҐͰҰ࣌ϑΝΠϧ Λ࡞ͬͯίϛοτ࣌ʹຊମʹॻ͖ࠐΉ • `sqlite3_busy_timeout` ଞͷεϨου/ϓϩηε͕ϩοΫ͍ͯ͠Δ࣌ʹ ॻ͖ࠐ΋͏ͱͨ࣌͠ʹԿඵ͔଴ͭ

Slide 28

Slide 28 text

GoͰRailsతʹ։ൃ͢Δ • ࠷ۙ࢓ࣄͰ΍Δ࣌ʹ࠾༻͢ΔελοΫ tanukirpc + sqlla • ϑϩϯτΤϯυ͸TanStack Router + React + Vite • tanukirpcͱsqlla͸boilerplateͳίʔυΛgenericsͱίʔυੜ੒Ͱ࡟ݮ͢ΔΞ ϓϩʔν • Rails͸gemͱDSLͰ࡟ݮ͍ͯ͠Δ • ݸਓతʹ͸͜ͷ૊Έ߹Θ͕ͤܕ෇͖ͰϫϯόΠφϦͰు͚ΔRailsͱͯ͠ೝࣝ͠ ͍ͯΔ

Slide 29

Slide 29 text

໰͍: ຊ౰ʹDocker͕ඞཁͳͷ͔ʁ • RailsͷΑ͏ͳRubyͱଟ਺ͷgemͰಈ࡞͢ΔͳΒ͋ͬͨํ͕ྑͦ͞͏ • σϓϩΠͷύοέʔδϯά͕DockerͰ୲͑Δ • gem͕OSଆͷڞ༗ϥΠϒϥϦʹґଘ͍ͯ͠Δέʔε΋ • ෳ਺ͷϓϩηεͰಈ͘ͳΒ͋ͬͨํ͕ྑͦ͞͏

Slide 30

Slide 30 text

GoͷΑ͏ͳϫϯόΠφϦͳΒͲ͏͔ʁ • ϫʔΧʔͱ͔΋1ͭͷϓϩηεʹ·ͱΊͯgoroutineͰಈ͔ͪ͠Ό͏ • Graceful Shutdown΍ႈ౳ੑ͸ؤுΖ͏ • σϓϩΠ΋γϯϓϧʹखݩorCIͰϏϧυ => rsync => ࠶ىಈͰྑ͍ • ઌ΄ͲͷGraceful RestartͷσϞͰࣔͨ͠server_starterͷྫ

Slide 31

Slide 31 text

ϑϩϯτΤϯυ͸Ͳ͏΍ͬͯ഑Δʁ • `//go:embed` Λ࢖༻͢Δ • ϑΝΠϧ΍σΟϨΫτϦΛؙ͝ͱϓϩάϥϜͷόΠφϦ಺ʹ֨ೲ͢Δ • io/fs.FSΠϯλʔϑΣΠεΛ࣮૷͍ͯ͠ΔͷͰͦͷ··ϑΝΠϧγες ϜͷΑ͏ʹϓϩάϥϜ಺෦Ͱ͸ѻ͑Δ • embedͰϏϧυͨ͠ϑϩϯτΤϯυΛ֨ೲ͢Δ

Slide 32

Slide 32 text

ະղܾͷ໰୊: σϓϩΠͨ͠Βݹ͍ΞηοτʹΞ ΫηεͰ͖ͳ͘ͳͬͨ • σϓϩΠޙʹϒϥ΢β͕อ͍࣋ͯ͠Δݹ͍index.htmlͳͲ͕ಡ΋͏ͱ͍ͯ͠Δݹ͍JS΍CSSΛಡ΋ ͏ͱͯ͠404ʹͳΔ݅ • kamal-proxyͰ͸ղܾͰ͖͍ͯΔ • υΩϡϝϯτΛಡΉͱ྆ํอ͍࣋ͯ͠ΔͬΆ͍ʁ • ͠͹Β͘ݹ͍΍ͭ΋࣋ͭͷ͕͍͍ΜͰ͠ΐ͏͔ • CloudFront + S3Ͱ͸Α͘΍͍ͬͯͨखஈͰ͋Δ͕… • `window.addEventListener(‘error’, …)`Ͱ`location.reload()`͢Δํ๏΋Ͱ͖ͦ͏ʁ • ΋͘͠͸Service Worker?

Slide 33

Slide 33 text

ͦͷଞͷ࿩୊: ingress௨৴ • ϙʔτ22൪Λ։͚Δͷ͸͔ͳΓݏ • tailscaleಥͬࠐΜͰຊ෺sshd͸࢖ΘͣʹTailscaleܦ༝ͰϩάΠϯ͍ͯ͠Δ • ͋ͱ͸ufwͰtailscaleҎ֎͔Βͷ֎͔Βͷ௨৴Λશ෦࠹͙ • 443൪։͚ͨ͘ͳ͍ • ͦΜͳ࣌ʹ࢖͑Δͷ͕Cloud fl are Tunnel • cloud fl aredΛཱͯͯɺCloud fl areͰड͚ͨϦΫΤετΛτϯωϧܦ༝Ͱड͚Δ • cloud fl ared͸egressͷ௨৴͔͠͠ͳ͍ͷͰϙʔτ͸։͚Δඞཁ͕ͳ͍

Slide 34

Slide 34 text

͞Βʹͦͷଞ • daemonize • ੲ͸supervisordͱ͔daemontoolsͱ͔͚͋ͬͨΕͲࠓ͸systemdͰ͍͍ͱࢥ͏Α • cron • systemdͰ͍͍ͱࢥ͏Α • ٖࣅcronϫʔΧʔΛgoroutineͰཱͯΔͷ͸͋Γ • ϩά • systemdͰ͍͍ͱࢥ͏Α • ݕࡧ౳Ͱू໿͕ཉ͔ͬͨ͠ΒS3ͱ͔ʹͳΜΒ͔ϩάίϨΫλͰඈ͹͢ͷ͕͍͍ΜͰ͔͢Ͷ͑ • ؂ࢹ • Mackerelͱ͔NewRelicͱ͔ • ࣗલmisskeyαʔόʔ͸NewRelicೖΕͯΔ • ϓϩϏδϣχϯά • mitamae͔ͳ͋ systemdͷunitϑΝΠϧΛಥͬࠐΉͷࣗ࡞ͯ͠΋͔͑͑΋͠ΕΜ

Slide 35

Slide 35 text

Ҏ্ GoͰϫϯόΠφϦ+SQLiteͰαʔϏε ߏஙͷ࿩Ͱͨ͠