Upgrade to Pro — share decks privately, control downloads, hide ads and more …

はてなにおけるマイクロサービスとScala / Microservices and Scala at Hatena

aereal
October 08, 2016

はてなにおけるマイクロサービスとScala / Microservices and Scala at Hatena

Scala関西Summit 2016 (http://summit.scala-kansai.org/) の発表資料です。

aereal

October 08, 2016
Tweet

More Decks by aereal

Other Decks in Programming

Transcript

  1. ͸ͯͳʹ͓͚Δ
    ϚΠΫϩαʔϏεͱScala
    id:aereal

    View Slide

  2. ࣗݾ঺հ
    • id:aereal
    • גࣜձࣾ͸ͯͳ (2012ʙ)
    • ͸ͯͳϒοΫϚʔΫ
    • ͸ͯͳϒϩά
    • Perl, Ruby, Scala, Shell Script

    View Slide

  3. ΞδΣϯμ
    • ৽ (ϚΠΫϩ) αʔϏεʹ͍ͭͯ
    • ͳͥϚΠΫϩαʔϏε͔
    • ͳͥScala͔
    • DDDͷ࣮ફ

    View Slide

  4. DISCLAIMER
    • ։ൃதͷ಺༰ؚ͕·Ε·͢
    • ࣮ࡍͷϦϦʔε࣌ʹ͸มߋ͞Ε͍ͯΔՄೳੑ͋Γ

    View Slide

  5. ৽αʔϏεʹ͍ͭͯ

    View Slide

  6. http://hatenablog.com/

    View Slide

  7. “͸ͯͳϒϩάΛ΋ͬͱຊ֨తʹ࢖͍͍ͨํͷͨ
    Ίʹɺ༗ྉϓϥϯʮ͸ͯͳϒϩάProʯΛ༻ҙ͠
    ͓ͯΓ·͢ɻ޿ࠂͷඇදࣔ΍ಠࣗυϝΠϯػೳ
    ͳͲɺ͸ͯͳϒϩάΛΑΓศརʹ͓࢖͍͍ͨͩ
    ͚·͢ɻ”
    http://hatenablog.com/guide/pro

    View Slide

  8. ͸ͯͳϙΠϯτ
    ΫϨδοτΧʔυ
    ίϯϏχৼࠐ
    ۜߦৼࠐ
    ࢖༻
    https://www.hatena.ne.jp/shop/point/list

    View Slide

  9. http://hatena.g.hatena.ne.jp/hatena/20150529/1432869070

    View Slide

  10. վम or ࡞Γ௚͠
    • طଘͷγεςϜ͸ϞϊϦγοΫ
    • ܾࡁͯ͠͸ͯͳϙΠϯτΛνϟʔδ͢Δ
    • ͸ͯͳϙΠϯτΛ࢖ͬͯߪೖ͢Δ
    • ࢓༷Λ੔ཧ͢Δ͍͍ػձͰ΋͋Δ

    View Slide

  11. ܾࡁ୅ߦαʔϏε

    (֎෦)
    ͸ͯͳͷαʔϏε
    (ϒοΫϚʔΫͳͲ)
    ݱߦܾࡁγεςϜ
    ϙΠϯτ؅ཧ
    ڞ༗Ϟδϡʔϧ
    ༗ྉϓϥϯ؅ཧ
    ґଘ
    ͸ͯͳͷαʔϏε
    ґଘ
    ͸ͯͳͷαʔϏε
    ґଘ
    etc. ΞΧ΢ϯτ

    View Slide

  12. ݱߦܾࡁγεςϜͷߏ੒
    • ܾࡁγεςϜ: WebΞϓϦέʔγϣϯ
    • API͸ͳ͘HTMLͷϑΥʔϜ͕͋ΔͷΈ
    • ڞ༗Ϟδϡʔϧ: ܾࡁ୅ߦαʔϏεͱ௨৴͢Δ࣮૷
    • ͨ͘͞ΜͷϦϙδτϦ͔Βґଘ͞Ε͍ͯΔ
    • ڞ༗DBΛૢ࡞͢Δ

    View Slide

  13. ݱߦܾࡁγεςϜͷվम
    • ΄ͱΜͲݱ࣮తͰ͸ͳ͍
    • ޓ׵ੑʹؔ͢ΔεΩʔϜ͕ͳ͍
    • ׬શޙํޓ׵ or die
    • ෳ਺ͷυϝΠϯ͕ೖΓཚΕ͍ͯΔ
    • ݱࡏͷ࢓༷ʹӨڹΛڧ͘ड͚Δ
    • վળ͕·ΘΒͳ͍

    View Slide

  14. ϑϧεΫϥον

    View Slide

  15. ৽ܾࡁγεςϜ
    • ܾࡁ୅ߦαʔϏεͷήʔτ΢ΣΠͱͯ͠ಇ͘
    • ͸ͯͳϒϩάProͷ෇༩ͳͲ͸֤αʔϏεʹҠৡ
    • JSON over HTTPͳAPIͷΈΛఏڙ͢Δ
    • ର৅͸SSKDs (= small set of known developers)

    View Slide

  16. ৽ܾࡁγεςϜ

    ߏ੒ਤ
    ܾࡁ୅ߦαʔϏε

    (֎෦)
    ͸ͯͳͷαʔϏε
    ༗ྉϓϥϯͷ
    ঢ়ଶ؅ཧ
    ৽ܾࡁγεςϜ

    View Slide

  17. چ ৽

    View Slide

  18. ׬

    View Slide

  19. ͳͥϚΠΫϩαʔϏε͔

    View Slide

  20. ϚΠΫϩαʔϏεͰ࡞Δ͔
    • 1ʙ3ষʹ͔͚ͯϝϦοτ΍
    ʮ༏ΕͨαʔϏεʯʹ͍ͭͯ
    ड़΂ΒΕ͍ͯΔ
    • ϚΠΫϩαʔϏεʹΑͬͯ

    αʔϏε͸ΑΓΑ͘ͳΔͷ͔
    • ΨόφϯεͳͲɺ

    ίετ͸෷͑ΔͩΖ͏͔
    https://www.oreilly.co.jp/books/9784873117607/

    View Slide

  21. ૄ݁߹ͱߴڽूੑ
    1. ϞϊϦγοΫͰखΛೖΕͮΒ͍ (ີ݁߹)
    2. ৽ͨʹ༗ྉϓϥϯΛಋೖ͍ͨ͠αʔϏε͸࠶࣮૷
    3. υϝΠϯ஌͕ࣝྲྀग़ (௿ڽूੑ)
    4.

    View Slide

  22. ࣋ଓՄೳʹ࡞Γ (ͳ͓͠) ͍ͨ
    • είʔϓΛখ͘͞໌ྎʹอͭ
    • ૄ݁߹ (ʰϚΠΫϩαʔϏεΞʔΩςΫνϟʱ3.2.1)
    • ߴڽूੑ (ʰϚΠΫϩαʔϏεΞʔΩςΫνϟʱ3.2.2)
    • ෼ׂ౷࣏͢Δ
    • ٕज़ҟ࣭ੑ (͍ͭ·Ͱ΋Perl͸ݫ͍͠)
    • σϓϩΠͷϥΠϑαΠΫϧΛૣΊΔ

    View Slide

  23. νʔϜؒ࿈ܞͷ

    Ή͔ͣ͠͞ͱઓ͏

    View Slide

  24. ΠϯηϓγϣϯσοΩΛ࡞Δ
    • ۙ͝ॴ͞ΜΛ໌Β͔ʹ͢Δ
    • ϝϯς͸Ͳ͜ʹҾ͖ܧ͙ͷ͔
    • ԿΛ༏ઌ͢Δͷ͔ (ఘΊΔͷ͔) Λ͸͖ͬΓͤ͞Δ
    • είʔϓɺ඼࣭ɺ༧ࢉɺεέδϡʔϧ
    • ʰΞδϟΠϧαϜϥΠʱ

    View Slide

  25. ͳͥϚΠΫϩαʔϏε͔: ·ͱΊ
    • ࠓճ͸ϚΠΫϩαʔϏεͰ΍͍ͬͯ͘
    • ಘΒΕΔϝϦοτ > ෷͏ίετ
    • ΨόφϯεͳͲෆ҆ͳ఺ʹ΋खΛଧͭ
    • ΠϯηϓγϣϯσοΩ
    • ૣ͔͘Βר͖ࠐΉ

    View Slide

  26. ׬

    View Slide

  27. ͳͥScala͔

    View Slide

  28. ࣮૷ݴޠΛܾΊΔ
    • ͸ͯͳͷબ୒ࢶͱͯ͠͸Perl, Go, ͦͯ͠Scala
    • ৽ܾࡁγεςϜͷίΞυϝΠϯʹٕज़ͦͷ΋ͷ͸

    ؚ·Εͳ͍
    • ϦεΫΛͱͬͯଞͷ৽ͨͳݴޠΛ࠾༻͢Δ

    ϝϦοτ͸ബ͍

    View Slide

  29. ࣮૷ݴޠΛܾΊΔ
    • ͳʹ͔ࢦඪ͕΄͍͠
    • ؾ࣋ͪ͸͍Ζ͍Ζ͋Δ
    • ʮ޷͖͔ͩΒʯͰ΋͍͍͚Ͳ……
    • ͲΜͳPros/ConsΛݟͨͷ͔

    View Slide

  30. ඇػೳཁٻΛఆΊΔ
    • ISO 9126
    • functionality: ػೳੑ
    • reliability: ৴པੑ
    • usability: ࢖༻ੑ
    • efficiency: ޮ཰ੑ
    • maintainability: อकੑ
    • portability: Ҡ২ੑ

    View Slide

  31. ඇػೳཁٻΛఆΊΔ
    • ISO 9126
    • functionality: ػೳੑ
    • reliability: ৴པੑ
    • usability: ࢖༻ੑ
    • efficiency: ޮ཰ੑ
    • maintainability: อकੑ
    • portability: Ҡ২ੑ

    View Slide

  32. ݴޠΛબͿ্ͰٻΊΔ΋ͷ
    • ๛͔ͳදݱྗ
    • ෳࡶͳυϝΠϯΛաෆ଍ͳ͘දݱ͍ͨ͠
    • ֶशۂઢͷ؇΍͔͞
    • ։ൃεϐʔυΛૣΊʹߴΊ҆ఆ͍ͤͨ͞
    • কདྷɺ։ൃ͢Δਓʹ΋΍͘͞͠

    View Slide

  33. ෳࡶͳυϝΠϯ
    • ঢ়ଶ΍ߟྀ͢΂͖ม਺͕ೖΓ૊ΜͰ͍Δ
    • ΫϨδοτΧʔυͷ༗ޮظݶ͕੾Ε͍ͯͨΒ?
    • ܾࡁ୅ߦαʔϏε͕མ͍ͪͯͨΒ?

    View Slide

  34. ঢ়ଶΛྻڍܕͰදݱ͢Δ
    sealed trait State
    object State {
    case object Requested extends State
    case object Paid extends State
    case object Failed extends State
    }
    ※࣮ࡍ͸΋͏ͪΐͬͱ͍Ζ͍Ζ͋Γ·͢

    View Slide

  35. ঢ়ଶΛྻڍܕͰදݱ͢Δ
    case class Payment(state: State) {
    def charged: Boolean = state match {
    case State.Paid => true
    case _ => false
    }
    }

    View Slide

  36. ঢ়ଶΛྻڍܕͰදݱ͢Δ
    • sealedम০͢ΔͱmatchࣜͰ໢ཏੑνΣοΫͰ͖Δ
    • ͱΓ͏Δঢ়ଶʹ໊͍ͭͯલΛ༩͑ΒΕΔ
    • ʮPaid͔FailedʹͳͬͨΒͦͷPayment͸

    ऴ୺͠·͢Ͷʯ

    View Slide

  37. Scalaͷֶशۂઢ……?
    • ؇΍͔Ͱ͸ͳ͍! (ݸਓͷݟղ)
    • ͔͠͠͸ͯͳͰ͸ࢧԉ͢Δ؀ڥΛ੔͖͑ͯͨ
    • ࣄྫ (Mackerel, ͸ͯͳϒοΫϚʔΫϦχϡʔΞϧ)
    • ͸ͯͳڭՊॻ github.com/hatena/Hatena-Textbook
    • ScalaͷఆੴΛ୳Δձ

    View Slide

  38. ScalaͷఆੴΛ୳Δձ
    • ϥΠϒϥϦ΍࣮૷ύλʔϯͷ஌ݟΛ࣋ͪدΔ
    • ScalaΛ࢖͍ͬͯΔνʔϜͷ༗ࢤͰ։࠵
    • Mackerel
    • ϒοΫϚʔΫϦχϡʔΞϧ
    • ৽ܾࡁγεςϜ

    View Slide

  39. ఆੴΛ୳ΔձͰ࿩ͨ͜͠ͱ
    • ϨΠϠߏ੒
    • ΞϓϦέʔγϣϯ૚
    • υϝΠϯ૚
    • Πϯϑϥ૚
    • બΜͩWAF/ORMͱͦͷഎܠ

    View Slide

  40. ͳͥScala͔: ·ͱΊ
    • ৽ܾࡁγεςϜ͕ٻΊΔཁ݅Λຬͨͯ͘͠Εͦ͏
    • ػೳੑ
    • อकੑ
    • ScalaΛॻ͘ΤϯδχΞΛҭͯΔ౔৕Λ੔͖͑ͯͨ
    • ScalaͷఆੴΛ୳ΔձɺڭՊॻ

    View Slide

  41. ׬

    View Slide

  42. DDDͷ࣮ફ

    View Slide

  43. DDD͍ͨ͠
    • υϝΠϯΤΩεύʔτͷ஌͕ࣝ

    ͦͷ··མͱ͠ࠐ·ΕͨαʔϏεʹ͍ͨ͠
    • ཁૉٕज़ (Πϯϑϥ૚) ͱ෼཭Մೳʹ͍ͨ͠
    • ࠷ѱ·ͨ࡞Γ௚͢͜ͱʹͳͬͯ΋

    ΑΓ௧ΈΛগͳ͍ͨ͘͠

    View Slide

  44. ݱߦܾࡁγεςϜͷ൓ল
    • ํ਑͕పఈ͞Εͳ͔ͬͨ
    • ʮApp͸΋͏ͩΊͩɺServiceͰ΍Γͳ͓ͦ͏ʯ
    • ಺੡ͷPerl൛Active RecordతORM
    • ϞσϧɺαʔϏεɺϦϙδτϦ͕ᕒવҰମ
    • Perlͷݶք
    • ΠϯλʔϑΣʔε͕ͳ͍
    • ΧϓηϧԽ͕ۃΊͯࠔ೉

    View Slide

  45. ͸ͯͳϒοΫϚʔΫ in Scala

    View Slide

  46. [PR]

    PerlͰ΋ΠέͯΔ։ൃ͍ͯ͠·͢
    Perlͷ্ʹ΋ࡾ೥

    ʙͣͬͱΠέͯΔαʔϏεΛ࡞Γଓ͚Δٕज़ʙ
    http://yapcasia.org/2015/talk/show/de9e7a1e-136d-11e5-a9fc-
    d9f87d574c3a

    View Slide

  47. DDD஥ؒ

    View Slide

  48. ͸ͯͳࣾ಺Ͱ։࠵ͨ͠

    DDDษڧձͷ༷ࢠΛ͝঺հ͠·͢
    http://developer.hatenastaff.com/entry/2015/08/20/170300

    View Slide

  49. ΤϦοΫɾΤϰΝϯεͷ

    υϝΠϯۦಈઃܭ
    http://www.shoeisha.co.jp/book/detail/9784798126708

    View Slide

  50. ࣮ફυϝΠϯۦಈઃܭ
    http://www.shoeisha.co.jp/book/detail/9784798131610

    View Slide

  51. ࣾ಺DDDษڧձ

    View Slide

  52. ࣾ಺DDDษڧձ
    • ਎ۙͳέʔεʹ͍ͭͯٞ࿦
    • ৽͘͠࡞ΔͳΒɺ͍·͔Βվળ͢ΔͳΒ
    • ֎ͷੈքͷ஌ݟΛڞ༗
    • ʮScalaͩͱ͜͏͍͏ػೳ͕͋ͬͯ……ʯ
    • ʮHaskellͩͱ……ʯ
    • ʮRubyͷ˓˓ͱ͍͏ϥΠϒϥϦ͸……ʯ

    View Slide

  53. DDDͷ࣮ફͱ࡞ઓ

    View Slide

  54. ೰Μͩͱ͜ΖɾݟͲ͜Ζ
    • ΤϯςΟςΟͷදݱ
    • ґଘੑͷ஫ೖ (DI)
    • cake pattern
    • αϒϓϩδΣΫτԽ
    • layering violationΛ๷͙

    View Slide

  55. ΤϯςΟςΟͷදݱ

    View Slide

  56. ΤϯςΟςΟͷදݱ
    • ΤϯςΟςΟ͸ૉ๿ͳcase class
    • ORM͸Slick
    • tarao/slick-jdbc-extensionΛ࢖ͬͯੜSQLͰҾ͍ͯ

    case class΁Ϛοϐϯά

    View Slide

  57. ΤϯςΟςΟͷදݱ
    • ΤϯςΟςΟ = ID + υϝΠϯϞσϧ
    • ܕ΋ύϥϝʔλԽ͞Ε͍ͯΔ
    • υϝΠϯϞσϧʹରͯ͠ڞม
    • ಉ͡IDܕ͕ͩυϝΠϯϞσϧ͕ҟͳΔ

    ΤϯςΟςΟΛఆٛͰ͖Δ

    View Slide

  58. ίʔυྫ
    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)

    View Slide

  59. ίʔυྫ
    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

    View Slide

  60. ίʔυྫ
    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)
    ஋ܕΛڞมʹ

    View Slide

  61. ίʔυྫ
    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ͷܕͷαϒΫϥεͰ͋Δ

    ܕύϥϝʔλ੍໿

    View Slide

  62. cake pattern

    View Slide

  63. ΠϯλʔϑΣʔεΛఆٛ
    package repo
    trait AccountComponent {
    def accountLoader: AccountLoader
    trait AccountLoader
    }

    View Slide

  64. ࣮૷
    package infra.db
    trait AccountComponent
    extends repo.AccountComponent {
    def accountLoader: AccountLoader =
    AccountDB
    object AccountDB extends AccountLoader
    { ... }
    }

    View Slide

  65. ґଘͷએݴͱ࢖༻
    package app
    trait AccountApp {
    self: repo.AccountComponent =>
    accountLoader.find(...)
    }

    View Slide

  66. ґଘͷ஫ೖ
    package main
    object Root
    extends app.AccountApp
    with infra.db.AccountComponent

    View Slide

  67. cake pattern
    • ίϯύΠϧλΠϜͰDI͞ΕΔ
    • Playͷίϯτϩʔϥ΋cake componentͱͯ͠߹੒

    View Slide

  68. DDDͷ࣮ફ: ·ͱΊ
    • ࣾ಺ษڧձͰʰ࣮ફDDDʱΛྠಡɺ஌ݟΛڞ༗
    • զʑʹͱͬͯͪΐ͏ͲΑ͍DDDΛݟ͚ͭΔ
    • ScalaͷྗΛ׆͔࣮ͨ͠૷ύλʔϯͷൃݟ

    View Slide

  69. ׬

    View Slide

  70. ·ͱΊ
    • ۜͷ஄ؙ͸ͳ͍!
    • ཁ݅ʹ͍͋ͬͯΔ͔ߟ͑Δ
    • ཁ݅ʹ͋ΘͤͯΞϨϯδ͍ͯ͘͠
    • ʮͪΐ͏Ͳ͍͍DDDʯ
    • ʮͪΐ͏Ͳ͍͍ϚΠΫϩαʔϏεʯ
    • ࣌ʹ͸ࣃΛ৯͍͠͹Δ

    View Slide