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
はてなにおけるマイクロサービスとScala / Microservices and Scala...
Search
aereal
October 08, 2016
Programming
6
34k
はてなにおけるマイクロサービスとScala / Microservices and Scala at Hatena
Scala関西Summit 2016 (
http://summit.scala-kansai.org/
) の発表資料です。
aereal
October 08, 2016
Tweet
Share
More Decks by aereal
See All by aereal
How to send distibuted traces to Datadog using build own OpenTelemetry-Lambda distribution
aereal
3
200
好きな技術《コト》で、 生きていく技術 / life with what you like
aereal
5
2.3k
qron: Cloud Native Cron Alternativeの今
aereal
2
2.1k
自動作曲入門 / introduction to programatic music composition
aereal
1
530k
はてなブログ タグとCDK / The epic of AWS CDK and Hatena Blog Tag
aereal
3
200k
はてなブログ タグの技術選択 / The technical details of Hatena Blog Tag
aereal
3
200k
ブログサービスのHTTPS化を支えたAWSで作るピタゴラスイッチ / The construction of large scale TLS certificates management system with AWS
aereal
3
400k
AWSではてなブログの常時HTTPS配信をバーンとやる話 / The Epic of migration from HTTP to HTTPS on Hatena Blog with AWS
aereal
14
17k
ScalaとPerlでMicroservices in production / Building microservices with Perl and Scala in production
aereal
0
5.3k
Other Decks in Programming
See All in Programming
Jakarta EE meets AI
ivargrimstad
0
580
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
100
What’s New in Compose Multiplatform - A Live Tour (droidcon London 2024)
zsmb
1
470
Quine, Polyglot, 良いコード
qnighy
4
640
役立つログに取り組もう
irof
28
9.6k
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
聞き手から登壇者へ: RubyKaigi2024 LTでの初挑戦が 教えてくれた、可能性の星
mikik0
1
120
シールドクラスをはじめよう / Getting Started with Sealed Classes
mackey0225
4
640
Ethereum_.pdf
nekomatu
0
460
Duckdb-Wasmでローカルダッシュボードを作ってみた
nkforwork
0
120
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.1k
Nurturing OpenJDK distribution: Eclipse Temurin Success History and plan
ivargrimstad
0
860
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
27
4.3k
Designing for Performance
lara
604
68k
Building an army of robots
kneath
302
43k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Into the Great Unknown - MozCon
thekraken
32
1.5k
BBQ
matthewcrist
85
9.3k
Designing the Hi-DPI Web
ddemaree
280
34k
Practical Orchestrator
shlominoach
186
10k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
93
16k
4 Signs Your Business is Dying
shpigford
180
21k
Writing Fast Ruby
sferik
627
61k
Automating Front-end Workflow
addyosmani
1366
200k
Transcript
ͯͳʹ͓͚Δ ϚΠΫϩαʔϏεͱScala id:aereal
ࣗݾհ • id:aereal • גࣜձࣾͯͳ (2012ʙ) • ͯͳϒοΫϚʔΫ • ͯͳϒϩά
• Perl, Ruby, Scala, Shell Script
ΞδΣϯμ • ৽ (ϚΠΫϩ) αʔϏεʹ͍ͭͯ • ͳͥϚΠΫϩαʔϏε͔ • ͳͥScala͔ •
DDDͷ࣮ફ
DISCLAIMER • ։ൃதͷ༰ؚ͕·Ε·͢ • ࣮ࡍͷϦϦʔε࣌ʹมߋ͞Ε͍ͯΔՄೳੑ͋Γ
৽αʔϏεʹ͍ͭͯ
http://hatenablog.com/
“ͯͳϒϩάΛͬͱຊ֨తʹ͍͍ͨํͷͨ Ίʹɺ༗ྉϓϥϯʮͯͳϒϩάProʯΛ༻ҙ͠ ͓ͯΓ·͢ɻࠂͷඇදࣔಠࣗυϝΠϯػೳ ͳͲɺͯͳϒϩάΛΑΓศརʹ͓͍͍ͨͩ ͚·͢ɻ” http://hatenablog.com/guide/pro
ͯͳϙΠϯτ ΫϨδοτΧʔυ ίϯϏχৼࠐ ۜߦৼࠐ ༻ https://www.hatena.ne.jp/shop/point/list
http://hatena.g.hatena.ne.jp/hatena/20150529/1432869070
վम or ࡞Γ͠ • طଘͷγεςϜϞϊϦγοΫ • ܾࡁͯͯ͠ͳϙΠϯτΛνϟʔδ͢Δ • ͯͳϙΠϯτΛͬͯߪೖ͢Δ •
༷Λཧ͢Δ͍͍ػձͰ͋Δ
ܾࡁߦαʔϏε (֎෦) ͯͳͷαʔϏε (ϒοΫϚʔΫͳͲ) ݱߦܾࡁγεςϜ ϙΠϯτཧ ڞ༗Ϟδϡʔϧ ༗ྉϓϥϯཧ ґଘ ͯͳͷαʔϏε
ґଘ ͯͳͷαʔϏε ґଘ etc. ΞΧϯτ
ݱߦܾࡁγεςϜͷߏ • ܾࡁγεςϜ: WebΞϓϦέʔγϣϯ • APIͳ͘HTMLͷϑΥʔϜ͕͋ΔͷΈ • ڞ༗Ϟδϡʔϧ: ܾࡁߦαʔϏεͱ௨৴͢Δ࣮ •
ͨ͘͞ΜͷϦϙδτϦ͔Βґଘ͞Ε͍ͯΔ • ڞ༗DBΛૢ࡞͢Δ
ݱߦܾࡁγεςϜͷվम • ΄ͱΜͲݱ࣮తͰͳ͍ • ޓੑʹؔ͢ΔεΩʔϜ͕ͳ͍ • શޙํޓ or die •
ෳͷυϝΠϯ͕ೖΓཚΕ͍ͯΔ • ݱࡏͷ༷ʹӨڹΛڧ͘ड͚Δ • վળ͕·ΘΒͳ͍
ϑϧεΫϥον
৽ܾࡁγεςϜ • ܾࡁߦαʔϏεͷήʔτΣΠͱͯ͠ಇ͘ • ͯͳϒϩάProͷ༩ͳͲ֤αʔϏεʹҠৡ • JSON over HTTPͳAPIͷΈΛఏڙ͢Δ •
ରSSKDs (= small set of known developers)
৽ܾࡁγεςϜ ߏਤ ܾࡁߦαʔϏε (֎෦) ͯͳͷαʔϏε ༗ྉϓϥϯͷ ঢ়ଶཧ ৽ܾࡁγεςϜ
چ ৽
ͳͥϚΠΫϩαʔϏε͔
ϚΠΫϩαʔϏεͰ࡞Δ͔ • 1ʙ3ষʹ͔͚ͯϝϦοτ ʮ༏ΕͨαʔϏεʯʹ͍ͭͯ ड़ΒΕ͍ͯΔ • ϚΠΫϩαʔϏεʹΑͬͯ αʔϏεΑΓΑ͘ͳΔͷ͔ • ΨόφϯεͳͲɺ
ίετ͑ΔͩΖ͏͔ https://www.oreilly.co.jp/books/9784873117607/
ૄ݁߹ͱߴڽूੑ 1. ϞϊϦγοΫͰखΛೖΕͮΒ͍ (ີ݁߹) 2. ৽ͨʹ༗ྉϓϥϯΛಋೖ͍ͨ͠αʔϏε࠶࣮ 3. υϝΠϯ͕ࣝྲྀग़ (ڽूੑ) 4.
࣋ଓՄೳʹ࡞Γ (ͳ͓͠) ͍ͨ • είʔϓΛখ͘͞໌ྎʹอͭ • ૄ݁߹ (ʰϚΠΫϩαʔϏεΞʔΩςΫνϟʱ3.2.1) • ߴڽूੑ
(ʰϚΠΫϩαʔϏεΞʔΩςΫνϟʱ3.2.2) • ׂ౷࣏͢Δ • ٕज़ҟ࣭ੑ (͍ͭ·ͰPerlݫ͍͠) • σϓϩΠͷϥΠϑαΠΫϧΛૣΊΔ
νʔϜؒ࿈ܞͷ Ή͔ͣ͠͞ͱઓ͏
ΠϯηϓγϣϯσοΩΛ࡞Δ • ۙ͝ॴ͞ΜΛ໌Β͔ʹ͢Δ • ϝϯςͲ͜ʹҾ͖ܧ͙ͷ͔ • ԿΛ༏ઌ͢Δͷ͔ (ఘΊΔͷ͔) Λ͖ͬΓͤ͞Δ •
είʔϓɺ࣭ɺ༧ࢉɺεέδϡʔϧ • ʰΞδϟΠϧαϜϥΠʱ
ͳͥϚΠΫϩαʔϏε͔: ·ͱΊ • ࠓճϚΠΫϩαʔϏεͰ͍ͬͯ͘ • ಘΒΕΔϝϦοτ > ͏ίετ • ΨόφϯεͳͲෆ҆ͳʹखΛଧͭ
• ΠϯηϓγϣϯσοΩ • ૣ͔͘Βר͖ࠐΉ
ͳͥScala͔
࣮ݴޠΛܾΊΔ • ͯͳͷબࢶͱͯ͠Perl, Go, ͦͯ͠Scala • ৽ܾࡁγεςϜͷίΞυϝΠϯʹٕज़ͦͷͷ ؚ·Εͳ͍ • ϦεΫΛͱͬͯଞͷ৽ͨͳݴޠΛ࠾༻͢Δ
ϝϦοτബ͍
࣮ݴޠΛܾΊΔ • ͳʹ͔ࢦඪ͕΄͍͠ • ؾ͍࣋ͪΖ͍Ζ͋Δ • ʮ͖͔ͩΒʯͰ͍͍͚Ͳ…… • ͲΜͳPros/ConsΛݟͨͷ͔
ඇػೳཁٻΛఆΊΔ • ISO 9126 • functionality: ػೳੑ • reliability: ৴པੑ
• usability: ༻ੑ • efficiency: ޮੑ • maintainability: อकੑ • portability: Ҡ২ੑ
ඇػೳཁٻΛఆΊΔ • ISO 9126 • functionality: ػೳੑ • reliability: ৴པੑ
• usability: ༻ੑ • efficiency: ޮੑ • maintainability: อकੑ • portability: Ҡ২ੑ
ݴޠΛબͿ্ͰٻΊΔͷ • ๛͔ͳදݱྗ • ෳࡶͳυϝΠϯΛաෆͳ͘දݱ͍ͨ͠ • ֶशۂઢͷ؇͔͞ • ։ൃεϐʔυΛૣΊʹߴΊ҆ఆ͍ͤͨ͞ •
কདྷɺ։ൃ͢Δਓʹ͘͞͠
ෳࡶͳυϝΠϯ • ঢ়ଶߟྀ͖͢ม͕ೖΓΜͰ͍Δ • ΫϨδοτΧʔυͷ༗ޮظݶ͕Ε͍ͯͨΒ? • ܾࡁߦαʔϏε͕མ͍ͪͯͨΒ?
ঢ়ଶΛྻڍܕͰදݱ͢Δ sealed trait State object State { case object Requested
extends State case object Paid extends State case object Failed extends State } ※࣮ࡍ͏ͪΐͬͱ͍Ζ͍Ζ͋Γ·͢
ঢ়ଶΛྻڍܕͰදݱ͢Δ case class Payment(state: State) { def charged: Boolean =
state match { case State.Paid => true case _ => false } }
ঢ়ଶΛྻڍܕͰදݱ͢Δ • sealedम০͢ΔͱmatchࣜͰཏੑνΣοΫͰ͖Δ • ͱΓ͏Δঢ়ଶʹ໊͍ͭͯલΛ༩͑ΒΕΔ • ʮPaid͔FailedʹͳͬͨΒͦͷPayment ऴ͠·͢Ͷʯ
Scalaͷֶशۂઢ……? • ؇͔Ͱͳ͍! (ݸਓͷݟղ) • ͔ͯ͠͠ͳͰࢧԉ͢ΔڥΛ͖͑ͯͨ • ࣄྫ (Mackerel, ͯͳϒοΫϚʔΫϦχϡʔΞϧ)
• ͯͳڭՊॻ github.com/hatena/Hatena-Textbook • ScalaͷఆੴΛ୳Δձ
ScalaͷఆੴΛ୳Δձ • ϥΠϒϥϦ࣮ύλʔϯͷݟΛ࣋ͪدΔ • ScalaΛ͍ͬͯΔνʔϜͷ༗ࢤͰ։࠵ • Mackerel • ϒοΫϚʔΫϦχϡʔΞϧ •
৽ܾࡁγεςϜ
ఆੴΛ୳ΔձͰͨ͜͠ͱ • ϨΠϠߏ • ΞϓϦέʔγϣϯ • υϝΠϯ • Πϯϑϥ •
બΜͩWAF/ORMͱͦͷഎܠ
ͳͥScala͔: ·ͱΊ • ৽ܾࡁγεςϜ͕ٻΊΔཁ݅Λຬͨͯ͘͠Εͦ͏ • ػೳੑ • อकੑ • ScalaΛॻ͘ΤϯδχΞΛҭͯΔΛ͖͑ͯͨ
• ScalaͷఆੴΛ୳ΔձɺڭՊॻ
DDDͷ࣮ફ
DDD͍ͨ͠ • υϝΠϯΤΩεύʔτͷ͕ࣝ ͦͷ··མͱ͠ࠐ·ΕͨαʔϏεʹ͍ͨ͠ • ཁૉٕज़ (Πϯϑϥ) ͱՄೳʹ͍ͨ͠ • ࠷ѱ·ͨ࡞Γ͢͜ͱʹͳͬͯ
ΑΓ௧ΈΛগͳ͍ͨ͘͠
ݱߦܾࡁγεςϜͷল • ํ͕పఈ͞Εͳ͔ͬͨ • ʮApp͏ͩΊͩɺServiceͰΓͳ͓ͦ͏ʯ • ͷPerl൛Active RecordతORM • ϞσϧɺαʔϏεɺϦϙδτϦ͕ᕒવҰମ
• Perlͷݶք • ΠϯλʔϑΣʔε͕ͳ͍ • ΧϓηϧԽ͕ۃΊͯࠔ
ͯͳϒοΫϚʔΫ in Scala
[PR] PerlͰΠέͯΔ։ൃ͍ͯ͠·͢ Perlͷ্ʹࡾ ʙͣͬͱΠέͯΔαʔϏεΛ࡞Γଓ͚Δٕज़ʙ http://yapcasia.org/2015/talk/show/de9e7a1e-136d-11e5-a9fc- d9f87d574c3a
DDDؒ
ͯͳࣾͰ։࠵ͨ͠ DDDษڧձͷ༷ࢠΛ͝հ͠·͢ http://developer.hatenastaff.com/entry/2015/08/20/170300
ΤϦοΫɾΤϰΝϯεͷ υϝΠϯۦಈઃܭ http://www.shoeisha.co.jp/book/detail/9784798126708
࣮ફυϝΠϯۦಈઃܭ http://www.shoeisha.co.jp/book/detail/9784798131610
ࣾDDDษڧձ
ࣾDDDษڧձ • ۙͳέʔεʹ͍ͭͯٞ • ৽͘͠࡞ΔͳΒɺ͍·͔Βվળ͢ΔͳΒ • ֎ͷੈքͷݟΛڞ༗ • ʮScalaͩͱ͜͏͍͏ػೳ͕͋ͬͯ……ʯ •
ʮHaskellͩͱ……ʯ • ʮRubyͷ˓˓ͱ͍͏ϥΠϒϥϦ……ʯ
DDDͷ࣮ફͱ࡞ઓ
Μͩͱ͜ΖɾݟͲ͜Ζ • ΤϯςΟςΟͷදݱ • ґଘੑͷೖ (DI) • cake pattern •
αϒϓϩδΣΫτԽ • layering violationΛ͙
ΤϯςΟςΟͷදݱ
ΤϯςΟςΟͷදݱ • ΤϯςΟςΟૉͳcase class • ORMSlick • tarao/slick-jdbc-extensionΛͬͯੜSQLͰҾ͍ͯ case classϚοϐϯά
ΤϯςΟςΟͷදݱ • ΤϯςΟςΟ = ID + υϝΠϯϞσϧ • ܕύϥϝʔλԽ͞Ε͍ͯΔ •
υϝΠϯϞσϧʹରͯ͠ڞม • ಉ͡IDܕ͕ͩυϝΠϯϞσϧ͕ҟͳΔ ΤϯςΟςΟΛఆٛͰ͖Δ
ίʔυྫ case class EntityKey[ID]( val repr: String ) extends AnyVal
abstract class Entity[K, +V]( val id: EntityKey[K], val value: V )(implicit ev: V <:< K)
ίʔυྫ case class EntityKey[ID]( val repr: String ) extends AnyVal
abstract class Entity[K, +V]( val id: EntityKey[K], val value: V )(implicit ev: V <:< K) phantom type
ίʔυྫ case class EntityKey[ID]( val repr: String ) extends AnyVal
abstract class Entity[K, +V]( val id: EntityKey[K], val value: V )(implicit ev: V <:< K) ܕΛڞมʹ
ίʔυྫ case class EntityKey[ID]( val repr: String ) extends AnyVal
abstract class Entity[K, +V]( val id: EntityKey[K], val value: V )(implicit ev: V <:< K) ͷܕ͕IDͷܕͷαϒΫϥεͰ͋Δ ܕύϥϝʔλ੍
cake pattern
ΠϯλʔϑΣʔεΛఆٛ package repo trait AccountComponent { def accountLoader: AccountLoader trait
AccountLoader }
࣮ package infra.db trait AccountComponent extends repo.AccountComponent { def accountLoader:
AccountLoader = AccountDB object AccountDB extends AccountLoader { ... } }
ґଘͷએݴͱ༻ package app trait AccountApp { self: repo.AccountComponent => accountLoader.find(...)
}
ґଘͷೖ package main object Root extends app.AccountApp with infra.db.AccountComponent
cake pattern • ίϯύΠϧλΠϜͰDI͞ΕΔ • Playͷίϯτϩʔϥcake componentͱͯ͠߹
DDDͷ࣮ફ: ·ͱΊ • ࣾษڧձͰʰ࣮ફDDDʱΛྠಡɺݟΛڞ༗ • զʑʹͱͬͯͪΐ͏ͲΑ͍DDDΛݟ͚ͭΔ • ScalaͷྗΛ׆͔࣮ͨ͠ύλʔϯͷൃݟ
·ͱΊ • ۜͷؙͳ͍! • ཁ݅ʹ͍͋ͬͯΔ͔ߟ͑Δ • ཁ݅ʹ͋ΘͤͯΞϨϯδ͍ͯ͘͠ • ʮͪΐ͏Ͳ͍͍DDDʯ •
ʮͪΐ͏Ͳ͍͍ϚΠΫϩαʔϏεʯ • ࣌ʹࣃΛ৯͍͠Δ