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
210
好きな技術《コト》で、 生きていく技術 / life with what you like
aereal
5
2.4k
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.4k
Other Decks in Programming
See All in Programming
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
130
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
250
MCP with Cloudflare Workers
yusukebe
2
220
Recoilを剥がしている話
kirik
5
6.7k
テストケースの名前はどうつけるべきか?
orgachem
PRO
0
130
nekko cloudにおけるProxmox VE利用事例
irumaru
3
430
SymfonyCon Vienna 2025: Twig, still relevant in 2025?
fabpot
3
1.2k
複雑な仕様に立ち向かうアーキテクチャ
myohei
0
170
創造的活動から切り拓く新たなキャリア 好きから始めてみる夜勤オペレーターからSREへの転身
yjszk
1
130
Monixと常駐プログラムの勘どころ / Scalaわいわい勉強会 #4
stoneream
0
280
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
110
良いユニットテストを書こう
mototakatsu
7
2.2k
Featured
See All Featured
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
It's Worth the Effort
3n
183
28k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
0
98
Fashionably flexible responsive web design (full day workshop)
malarkey
405
66k
Facilitating Awesome Meetings
lara
50
6.1k
Code Reviewing Like a Champion
maltzj
520
39k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
127
18k
For a Future-Friendly Web
brad_frost
175
9.4k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Testing 201, or: Great Expectations
jmmastey
40
7.1k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
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ʯ •
ʮͪΐ͏Ͳ͍͍ϚΠΫϩαʔϏεʯ • ࣌ʹࣃΛ৯͍͠Δ