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

3f4be9784f765877f444bc839de29888?s=47 aereal
October 08, 2016

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

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

3f4be9784f765877f444bc839de29888?s=128

aereal

October 08, 2016
Tweet

Transcript

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

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

    • Perl, Ruby, Scala, Shell Script
  3. ΞδΣϯμ • ৽ (ϚΠΫϩ) αʔϏεʹ͍ͭͯ • ͳͥϚΠΫϩαʔϏε͔ • ͳͥScala͔ •

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

  5. ৽αʔϏεʹ͍ͭͯ

  6. http://hatenablog.com/

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

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

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

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

    ࢓༷Λ੔ཧ͢Δ͍͍ػձͰ΋͋Δ
  11. ܾࡁ୅ߦαʔϏε
 (֎෦) ͸ͯͳͷαʔϏε (ϒοΫϚʔΫͳͲ) ݱߦܾࡁγεςϜ ϙΠϯτ؅ཧ ڞ༗Ϟδϡʔϧ ༗ྉϓϥϯ؅ཧ ґଘ ͸ͯͳͷαʔϏε

    ґଘ ͸ͯͳͷαʔϏε ґଘ etc. ΞΧ΢ϯτ
  12. ݱߦܾࡁγεςϜͷߏ੒ • ܾࡁγεςϜ: WebΞϓϦέʔγϣϯ • API͸ͳ͘HTMLͷϑΥʔϜ͕͋ΔͷΈ • ڞ༗Ϟδϡʔϧ: ܾࡁ୅ߦαʔϏεͱ௨৴͢Δ࣮૷ •

    ͨ͘͞ΜͷϦϙδτϦ͔Βґଘ͞Ε͍ͯΔ • ڞ༗DBΛૢ࡞͢Δ
  13. ݱߦܾࡁγεςϜͷվम • ΄ͱΜͲݱ࣮తͰ͸ͳ͍ • ޓ׵ੑʹؔ͢ΔεΩʔϜ͕ͳ͍ • ׬શޙํޓ׵ or die •

    ෳ਺ͷυϝΠϯ͕ೖΓཚΕ͍ͯΔ • ݱࡏͷ࢓༷ʹӨڹΛڧ͘ड͚Δ • վળ͕·ΘΒͳ͍
  14. ϑϧεΫϥον

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

    ର৅͸SSKDs (= small set of known developers)
  16. ৽ܾࡁγεςϜ
 ߏ੒ਤ ܾࡁ୅ߦαʔϏε
 (֎෦) ͸ͯͳͷαʔϏε ༗ྉϓϥϯͷ ঢ়ଶ؅ཧ ৽ܾࡁγεςϜ

  17. چ ৽

  18. ׬

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

  20. ϚΠΫϩαʔϏεͰ࡞Δ͔ • 1ʙ3ষʹ͔͚ͯϝϦοτ΍ ʮ༏ΕͨαʔϏεʯʹ͍ͭͯ ड़΂ΒΕ͍ͯΔ • ϚΠΫϩαʔϏεʹΑͬͯ
 αʔϏε͸ΑΓΑ͘ͳΔͷ͔ • ΨόφϯεͳͲɺ


    ίετ͸෷͑ΔͩΖ͏͔ https://www.oreilly.co.jp/books/9784873117607/
  21. ૄ݁߹ͱߴڽूੑ 1. ϞϊϦγοΫͰखΛೖΕͮΒ͍ (ີ݁߹) 2. ৽ͨʹ༗ྉϓϥϯΛಋೖ͍ͨ͠αʔϏε͸࠶࣮૷ 3. υϝΠϯ஌͕ࣝྲྀग़ (௿ڽूੑ) 4.

  22. ࣋ଓՄೳʹ࡞Γ (ͳ͓͠) ͍ͨ • είʔϓΛখ͘͞໌ྎʹอͭ • ૄ݁߹ (ʰϚΠΫϩαʔϏεΞʔΩςΫνϟʱ3.2.1) • ߴڽूੑ

    (ʰϚΠΫϩαʔϏεΞʔΩςΫνϟʱ3.2.2) • ෼ׂ౷࣏͢Δ • ٕज़ҟ࣭ੑ (͍ͭ·Ͱ΋Perl͸ݫ͍͠) • σϓϩΠͷϥΠϑαΠΫϧΛૣΊΔ
  23. νʔϜؒ࿈ܞͷ
 Ή͔ͣ͠͞ͱઓ͏

  24. ΠϯηϓγϣϯσοΩΛ࡞Δ • ۙ͝ॴ͞ΜΛ໌Β͔ʹ͢Δ • ϝϯς͸Ͳ͜ʹҾ͖ܧ͙ͷ͔ • ԿΛ༏ઌ͢Δͷ͔ (ఘΊΔͷ͔) Λ͸͖ͬΓͤ͞Δ •

    είʔϓɺ඼࣭ɺ༧ࢉɺεέδϡʔϧ • ʰΞδϟΠϧαϜϥΠʱ
  25. ͳͥϚΠΫϩαʔϏε͔: ·ͱΊ • ࠓճ͸ϚΠΫϩαʔϏεͰ΍͍ͬͯ͘ • ಘΒΕΔϝϦοτ > ෷͏ίετ • ΨόφϯεͳͲෆ҆ͳ఺ʹ΋खΛଧͭ

    • ΠϯηϓγϣϯσοΩ • ૣ͔͘Βר͖ࠐΉ
  26. ׬

  27. ͳͥScala͔

  28. ࣮૷ݴޠΛܾΊΔ • ͸ͯͳͷબ୒ࢶͱͯ͠͸Perl, Go, ͦͯ͠Scala • ৽ܾࡁγεςϜͷίΞυϝΠϯʹٕज़ͦͷ΋ͷ͸
 ؚ·Εͳ͍ • ϦεΫΛͱͬͯଞͷ৽ͨͳݴޠΛ࠾༻͢Δ


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

  30. ඇػೳཁٻΛఆΊΔ • ISO 9126 • functionality: ػೳੑ • reliability: ৴པੑ

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

    • usability: ࢖༻ੑ • efficiency: ޮ཰ੑ • maintainability: อकੑ • portability: Ҡ২ੑ
  32. ݴޠΛબͿ্ͰٻΊΔ΋ͷ • ๛͔ͳදݱྗ • ෳࡶͳυϝΠϯΛաෆ଍ͳ͘දݱ͍ͨ͠ • ֶशۂઢͷ؇΍͔͞ • ։ൃεϐʔυΛૣΊʹߴΊ҆ఆ͍ͤͨ͞ •

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

  34. ঢ়ଶΛྻڍܕͰදݱ͢Δ sealed trait State object State { case object Requested

    extends State case object Paid extends State case object Failed extends State } ※࣮ࡍ͸΋͏ͪΐͬͱ͍Ζ͍Ζ͋Γ·͢
  35. ঢ়ଶΛྻڍܕͰදݱ͢Δ case class Payment(state: State) { def charged: Boolean =

    state match { case State.Paid => true case _ => false } }
  36. ঢ়ଶΛྻڍܕͰදݱ͢Δ • sealedम০͢ΔͱmatchࣜͰ໢ཏੑνΣοΫͰ͖Δ • ͱΓ͏Δঢ়ଶʹ໊͍ͭͯલΛ༩͑ΒΕΔ • ʮPaid͔FailedʹͳͬͨΒͦͷPayment͸
 ऴ୺͠·͢Ͷʯ

  37. Scalaͷֶशۂઢ……? • ؇΍͔Ͱ͸ͳ͍! (ݸਓͷݟղ) • ͔͠͠͸ͯͳͰ͸ࢧԉ͢Δ؀ڥΛ੔͖͑ͯͨ • ࣄྫ (Mackerel, ͸ͯͳϒοΫϚʔΫϦχϡʔΞϧ)

    • ͸ͯͳڭՊॻ github.com/hatena/Hatena-Textbook • ScalaͷఆੴΛ୳Δձ
  38. ScalaͷఆੴΛ୳Δձ • ϥΠϒϥϦ΍࣮૷ύλʔϯͷ஌ݟΛ࣋ͪدΔ • ScalaΛ࢖͍ͬͯΔνʔϜͷ༗ࢤͰ։࠵ • Mackerel • ϒοΫϚʔΫϦχϡʔΞϧ •

    ৽ܾࡁγεςϜ
  39. ఆੴΛ୳ΔձͰ࿩ͨ͜͠ͱ • ϨΠϠߏ੒ • ΞϓϦέʔγϣϯ૚ • υϝΠϯ૚ • Πϯϑϥ૚ •

    બΜͩWAF/ORMͱͦͷഎܠ
  40. ͳͥScala͔: ·ͱΊ • ৽ܾࡁγεςϜ͕ٻΊΔཁ݅Λຬͨͯ͘͠Εͦ͏ • ػೳੑ • อकੑ • ScalaΛॻ͘ΤϯδχΞΛҭͯΔ౔৕Λ੔͖͑ͯͨ

    • ScalaͷఆੴΛ୳ΔձɺڭՊॻ
  41. ׬

  42. DDDͷ࣮ફ

  43. DDD͍ͨ͠ • υϝΠϯΤΩεύʔτͷ஌͕ࣝ
 ͦͷ··མͱ͠ࠐ·ΕͨαʔϏεʹ͍ͨ͠ • ཁૉٕज़ (Πϯϑϥ૚) ͱ෼཭Մೳʹ͍ͨ͠ • ࠷ѱ·ͨ࡞Γ௚͢͜ͱʹͳͬͯ΋


    ΑΓ௧ΈΛগͳ͍ͨ͘͠
  44. ݱߦܾࡁγεςϜͷ൓ল • ํ਑͕పఈ͞Εͳ͔ͬͨ • ʮApp͸΋͏ͩΊͩɺServiceͰ΍Γͳ͓ͦ͏ʯ • ಺੡ͷPerl൛Active RecordతORM • ϞσϧɺαʔϏεɺϦϙδτϦ͕ᕒવҰମ

    • Perlͷݶք • ΠϯλʔϑΣʔε͕ͳ͍ • ΧϓηϧԽ͕ۃΊͯࠔ೉
  45. ͸ͯͳϒοΫϚʔΫ in Scala

  46. [PR]
 PerlͰ΋ΠέͯΔ։ൃ͍ͯ͠·͢ Perlͷ্ʹ΋ࡾ೥
 ʙͣͬͱΠέͯΔαʔϏεΛ࡞Γଓ͚Δٕज़ʙ http://yapcasia.org/2015/talk/show/de9e7a1e-136d-11e5-a9fc- d9f87d574c3a

  47. DDD஥ؒ

  48. ͸ͯͳࣾ಺Ͱ։࠵ͨ͠
 DDDษڧձͷ༷ࢠΛ͝঺հ͠·͢ http://developer.hatenastaff.com/entry/2015/08/20/170300

  49. ΤϦοΫɾΤϰΝϯεͷ
 υϝΠϯۦಈઃܭ http://www.shoeisha.co.jp/book/detail/9784798126708

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

  51. ࣾ಺DDDษڧձ

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

    ʮHaskellͩͱ……ʯ • ʮRubyͷ˓˓ͱ͍͏ϥΠϒϥϦ͸……ʯ
  53. DDDͷ࣮ફͱ࡞ઓ

  54. ೰Μͩͱ͜ΖɾݟͲ͜Ζ • ΤϯςΟςΟͷදݱ • ґଘੑͷ஫ೖ (DI) • cake pattern •

    αϒϓϩδΣΫτԽ • layering violationΛ๷͙
  55. ΤϯςΟςΟͷදݱ

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

  57. ΤϯςΟςΟͷදݱ • ΤϯςΟςΟ = ID + υϝΠϯϞσϧ • ܕ΋ύϥϝʔλԽ͞Ε͍ͯΔ •

    υϝΠϯϞσϧʹରͯ͠ڞม • ಉ͡IDܕ͕ͩυϝΠϯϞσϧ͕ҟͳΔ
 ΤϯςΟςΟΛఆٛͰ͖Δ
  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)
  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
  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) ஋ܕΛڞมʹ
  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ͷܕͷαϒΫϥεͰ͋Δ
 ܕύϥϝʔλ੍໿
  62. cake pattern

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

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

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

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

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

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

  69. ׬

  70. ·ͱΊ • ۜͷ஄ؙ͸ͳ͍! • ཁ݅ʹ͍͋ͬͯΔ͔ߟ͑Δ • ཁ݅ʹ͋ΘͤͯΞϨϯδ͍ͯ͘͠ • ʮͪΐ͏Ͳ͍͍DDDʯ •

    ʮͪΐ͏Ͳ͍͍ϚΠΫϩαʔϏεʯ • ࣌ʹ͸ࣃΛ৯͍͠͹Δ