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

How to play Scala on dockerized infrastructure

Naoki Ainoya
January 30, 2016

How to play Scala on dockerized infrastructure

At ScalaMatsuri 2016

Naoki Ainoya

January 30, 2016
Tweet

More Decks by Naoki Ainoya

Other Decks in Programming

Transcript

  1. HOW TO SCALA ON
    DOCKERIZED INFRASTRUCTURE
    NAOKI AINOYA
    RECRUIT MARKETING PARTNERS CO, LTD.
    SCALA MATSURI 2016

    View Slide

  2. ▸ Naoki Ainoya
    ▸ Server-side / Ops / 

    iOS App developer
    ABOUT ME

    View Slide

  3. ABOUT US
    ▸ Recruit Marketing Partners Co, Ltd
    ▸ Our business domain is in

    "Life Event"

    View Slide

  4. OUR PRODUCTS
    ▸ English education
    ▸ ӳ୯ޠαϓϦ (iOS/Android)
    ▸ ӳޠαϓϦ (iOS/Web)

    View Slide

  5. TECHNOLOGY
    STACK
    CLIENT-SIDE:
    IOS(SWIFT)/ANDROID/WEB(ANGULARJS)
    SERVER-SIDE:
    SCALA(PLAY FRAMEWORK)
    INFRASTRUCTURE:
    DOCKER(AWS/EC2 CONTAINER SERVICE)
    Client
    Server
    Infrastructure

    View Slide

  6. BACKEND ARCHITECTURE
    ▸ RESTful API Servers on EC2
    Container Service (ECS)
    ▸ Servers are properly
    decoupled by docker
    containers
    Client
    AUTH
    CS ETC..
    PUBLIC
    API
    ADMIN
    Docker Containers
    Data
    HTTPS
    MySQL Elasticache S3
    αʔό͸%PDLFSίϯςφʹΑͬͯ෼ׂɾૄ݁߹Խ

    View Slide

  7. WHY DO WE USE SCALA ?
    ▸ Scalable to develop
    ▸ Easy to adopt DDD style
    ▸ Easy to refactor
    4DBMB͸։ൃΛεέʔϧͤ͞΍͍͢

    View Slide

  8. EASY TO ADOPT DDD STYLE
    ▸ Easy to make DDD-style
    architecture
    ▸ Value object is defined as
    "object"
    ▸ Entity is defined as "case
    class"
    ▸ Separate layers with
    "protected"
    PRESENTATION
    DOMAIN
    DATA ACCESS
    Layered architecture
    ཧ༝ͷҰͭ͸%%%ͱ਌࿨ੑ͕ߴ͍͜ͱ

    View Slide

  9. EASY TO ADOPT DDD STYLE
    ▸ DDD-style makes good habits of
    Separation of Concerns (SoC)
    ▸ It keeps codes clean
    %%%Λҙࣝͨ͠։ൃͰίʔυ͕៉ྷʹอͨΕ΍͘͢ͳͬͨ
    PRESENTATION
    DOMAIN
    DATA ACCESS
    Layered architecture

    View Slide

  10. EASY TO REFACTOR
    ▸ Functional feature
    ▸ Static typing
    ϦϑΝΫλͷ͠΍͢͞΋ॏཁɿؔ਺ܕݴޠɾ੩తܕ෇͚

    View Slide

  11. FUNCTIONAL FEATURE HELPS CODE MAINTAINABLITY
    ▸ Minimize side-effects
    ▸ Handle errors in functional way
    ▸ Either \/ monad in Scalaz
    ▸ ScalazΛ࢖͓͏ #1 – NET BIZ DIV. TECH BLOG 

    http://tech.recruit-mp.co.jp/server-side/post-2540/
    Ϟφυ΍ؔ਺ܕͷಛ௃Λ׆༻ͯ͠มߋʹڧ͍ίʔυΛॻ͘

    View Slide

  12. I DON'T HAVE TO EMAIL
    EVERYONE IF I CHANGE
    FUNCTION NAMES ANYMORE.
    Developer
    STATIC TYPING
    ੩తܕ෇͚͸νʔϜ։ൃͷॿ͚ʹͳΔ

    View Slide

  13. SCALABLE TO DEVELOP
    ▸ Keep development stable
    against increasing
    developers
    2015/01 1 developer
    3 developers
    6+ developers
    2015/04
    Now
    ݁Ռͱͯ͠ϝϯόʔ͕ٸʹ૿͑ͯ΋҆શʹ։ൃͰ͖ͨ

    View Slide

  14. WHY DO WE USE DOCKER ?
    ▸ Make a infrastructure immutable

    like a Scala code
    ▸ Easy to keep an application
    environment clean
    ▸ Easy to deploy
    %PDLFSΛ࢖ͬͯΠϯϑϥ΋Πϛϡʔλϒϧͳӡ༻Ͱ

    View Slide

  15. EASY TO KEEP AN APPLICATION ENVIRONMENT CLEAN
    ▸ Easy to know in what
    environment server is running for
    devs
    ▸ Platform
    ▸ JDK version
    ▸ Timezone
    AUTH
    CS ETC..
    PUBLIC
    API
    ADMIN
    Production Environment
    DOCKER
    IMAGE
    Run containers
    %PDLFSʹΑͬͯ։ൃऀ͕ຊ൪؀ڥͷ༷ࢠΛ೺Ѳ͠΍͘͢ͳΔ

    View Slide

  16. EASY TO DEPLOY
    ▸ Simplify deploy system
    ▸ We only have to know how to

    docker run 

    in production
    AUTH
    CS ETC..
    PUBLIC
    API
    ADMIN
    Production Environment
    CODE
    Build Image &

    Deploy
    Devs
    ༰қͳσϓϩΠ͕Մೳ

    View Slide

  17. HOW ARE WE OPERATING
    SCALA/PLAY
    DEVELOPMENT
    TEST
    DEPLOYMENT
    SCHEDULED JOB
    DATABASE MANAGEMENT
    MONITORING

    View Slide

  18. DEVELOPMENT
    ▸ IntelliJ
    ▸ Great code completion
    ▸ Easy to debug
    ▸ Use MySQL container in local
    ▸ If It's needed

    (for migration test etc…)
    Docker Container

    in docker-machine

    (Virtualbox)
    H2 Database
    Unit test
    (In-memory DB)
    Switch

    if needed
    ։ൃʹ͸JOUFMMJ+Λར༻ɺ%#͸ඞཁʹԠͯ͡੾Γସ͑

    View Slide

  19. TEST
    ▸ Unit test
    ▸ Specs2
    ▸ with using H2Database

    (in-memory DB)
    ▸ Jenkins CI
    ▸ Run unit tests
    ▸ with using MySQL
    Devs
    Develop + Write Test
    Run tests each commits
    git push
    webhook
    +FOLJOT্Ͱͷςετ࣮ߦ͸.Z42-ͱ઀ଓ

    View Slide

  20. COMPILATION TIME
    ▸ It takes much time !
    ▸ Don't use sbt clean 

    if it's not needed
    ▸ Use incremental compile
    function if possible
    Clean & Test
    Test
    Test
    Test
    Clean & Test
    develop
    feature-A
    ίϯύΠϧ஗͘ͳΔͷͰ$MFBO͸ඞཁͳ࣌ʹ͔͠͠ͳ͍

    View Slide

  21. DEPLOYMENT
    develop
    feature-A
    master
    DEPLOY

    View Slide

  22. DEPLOYMENT
    develop
    feature-A
    master
    Build Docker image

    with

    sbt-native-packager
    ./activator docker:publish
    TCUOBUJWFQBDLFSͰ%PDLFSJNBHFΛϏϧυ

    View Slide

  23. DEPLOYMENT
    develop
    feature-A
    master
    Build Docker image

    with

    sbt-native-packager
    private registry
    Push docker image
    ./activator docker:publish
    ͦͷ··+FOLJOT্͔ΒQSJWBUFSFHJTUSZ΁ΠϝʔδΛQVTI

    View Slide

  24. DEPLOYMENT
    develop
    feature-A
    master
    Build Docker image

    with

    sbt-native-packager
    private registry
    Push docker image
    ECS
    Upgrade

    services

    via ECS API
    &$4"1*Λୟ͍ͯίϯςφΛσϓϩΠ

    View Slide

  25. DEPLOYMENT
    develop
    feature-A
    master
    Build Docker image

    with

    sbt-native-packager
    private registry
    Push docker image
    ECS
    Upgrade

    services

    via ECS API
    pull

    View Slide

  26. DEPLOYMENT
    develop
    feature-A
    master
    Build Docker image

    with

    sbt-native-packager
    private registry
    Push docker image
    ECS
    Upgrade

    services

    via ECS API
    pull
    AUTH
    CS ETC..
    PUBLIC
    API ADMIN
    Production Environment

    View Slide

  27. DEPLOYMENT
    develop
    feature-A
    master
    Build Docker image

    with

    sbt-native-packager
    private registry
    Push docker image
    ECS
    Upgrade

    services

    via ECS API
    pull
    AUTH
    CS ETC..
    PUBLIC
    API ADMIN
    Production Environment
    Switch server's role

    by application.conf
    ԿͷαʔόΛσϓϩΠ͢Δ͔͸DPOGϑΝΠϧͰࢦఆ

    View Slide

  28. CONFIGURATION MANAGEMENT
    ECS
    AUTH
    CS ETC..
    PUBLIC
    API ADMIN
    Production Environment
    Switch server's role

    by application.conf
    ▸ Prepare config files each
    server roles
    ▸ prod_api.conf/
    prod_admin.conf/
    prod_auth.conf etc…
    ▸ Choose config file with option

    JAVA_OPTS=

    -Dconfig.resource=prod_api.conf
    αʔόͷछྨ͝ͱʹDPOGϑΝΠϧΛ༻ҙ

    View Slide

  29. CONFIGURATION MANAGEMENT
    ▸ application.conf can also
    switch routing settings
    play {
    http {
    router = route.api.Routes
    }
    }
    prod_api.conf ECS
    AUTH
    CS ETC..
    PUBLIC
    API ADMIN
    Production Environment
    Switch server's role

    by application.conf
    DPOGϑΝΠϧͰΤϯυϙΠϯτͷ੾Γସ͑΋ߦ͏

    View Slide

  30. CONFIGURATION MANAGEMENT
    ▸ application.conf can also
    switch routing settings
    play {
    http {
    router = route.api.Routes
    }
    }
    prod_api.conf
    # Routes api.
    # ~~~~
    -> / route.partial.api.Routes
    -> / route.partial.common.Routes
    route.api.routes

    View Slide

  31. CONFIGURATION MANAGEMENT
    ▸ application.conf can also
    switch routing settings
    play {
    http {
    router = route.api.Routes
    }
    }
    prod_api.conf
    # Routes api.
    # ~~~~
    -> / route.partial.api.Routes
    -> / route.partial.common.Routes
    route.api.routes
    # partial Routes api.
    # ~~~~
    POST /api/v1/publish_id
    controllers.api.Auth.publishId


    route.partial.api.routes

    View Slide

  32. CONFIGURATION MANAGEMENT
    ▸ application.conf can also
    switch routing settings
    play {
    http {
    router = route.api.Routes
    }
    }
    prod_api.conf
    # Routes api.
    # ~~~~
    -> / route.partial.api.Routes
    -> / route.partial.common.Routes
    route.api.routes
    # partial Routes common.

    # ~~~~
    GET /
    controllers.Application.index
    # Map static resources from the /public
    folder to the /assets URL path



    route.partial.common.routes
    NOTE: If endpoint is duplicated, 

    Scala compile fails
    3PVUFTϑΝΠϧΛڞ௨Խ͢Δ

    View Slide

  33. SCHEDULED JOB
    ▸ Daily batch job
    ▸ Daily KPI reporting
    ▸ Scheduled by Jenkins
    Executes play application

    by one shot
    όον࣮ߦʹ͸+FOLJOTΛར༻

    View Slide

  34. EXECUTE PLAY APPLICATION BY ONE SHOT
    ▸ Create application jar file

    ./sbt clean assembly
    ▸ Execute jar

    Executes play application

    by one shot
    java -Dconfig.resource=batch.conf 

    -cp ./target/scala-2.11/app-x.x.jar

    tasks.SomeTask
    ίϯύΠϧࡁΈKBSΛεέδϡʔϧ࣮ߦ͢Δ

    View Slide

  35. EXECUTE PLAY APPLICATION BY ONE SHOT
    Executes play application

    by one shot
    java -Dconfig.resource=batch.conf 

    -cp ./target/scala-2.11/app-x.x.jar

    tasks.SomeTask
    package tasks
    import com.typesafe.scalalogging.LazyLogging
    object SomeTask extends App with Task with LazyLogging {
    withApplication(
    app => {
    doSomething() // Do something
    },
    ex => ex match {
    case ex =>
    logger.error(ex.getMessage, ex)
    println("Something went wrong")
    }
    )
    }
    ͍ͤͨ͞όονॲཧΛίϚϯυҾ਺Ͱࢦఆ

    View Slide

  36. DATABASE MANAGEMENT
    ▸ Slick 3.1
    ▸ Schema migration with Evolutions
    ▸ Enable useLocks option if you have Play nodes that may
    potential run evolutions
    ▸ Evolutions 

    https://www.playframework.com/documentation/2.4.x/Evolutions
    VTF-PDLTͰෳ਺୆σϓϩΠ࣌ͷFWPMVUJPOͷ๫ൃΛࢭΊΔ

    View Slide

  37. EVOLUTION BEFORE DEPLOYMENT
    ▸ Even if useLocks option is
    enabled,

    Evolution should be
    executed carefully
    ▸ Execute evolutions safely
    before deployments with
    one-shot style as a Jenkins
    job
    java -Dconfig.resource=batch.conf 

    -Dplay.evolutions.db.default.autoApply=true

    -Dplay.mode=prod

    -cp ./target/scala-2.11/app-x.x.jar

    tasks.EvolutionsCheckTask
    One-shot evolution example
    FWPMVUJPO͸σϓϩΠͷલʹ୯ମͰ࣮ߦ͓ͯ͘͠ͷ͕҆৺

    View Slide

  38. EVOLUTION BEFORE DEPLOYMENT
    ▸ Even if useLocks option is
    enabled,

    Evolution should be
    executed carefully
    ▸ Execute evolutions safely
    before deployments with
    one-shot style as a Jenkins
    job
    java -Dconfig.resource=batch.conf 

    -Dplay.evolutions.db.default.autoApply=true

    -Dplay.mode=prod

    -cp ./target/scala-2.11/app-x.x.jar

    tasks.EvolutionsCheckTask
    One-shot evolution example
    package tasks
    import com.typesafe.scalalogging.LazyLogging
    object EvolutionsCheckTask extends App with Task with LazyLogging
    {
    withApplication(
    app => {
    logger.info("unnecessary")
    },
    ex => ex match {
    case ex: play.api.db.evolutions.InvalidDatabaseRevision =>
    logger.warn("necessary")
    case ex =>
    logger.error(ex.getMessage, ex)
    println("Error")
    }
    )
    }
    tasks.EvolutionsCheckTask

    View Slide

  39. MONITORING
    ▸ Datadog watches system metrics
    ▸ Collect error logs with Errbit
    ▸ Errbit is OSS clone of Airbrake
    System metrics Error logs
    ௨ৗͷ؂ࢹ͸%BUB%PHͰɺΤϥʔϩά؂ࢹ͸&SSCJUΛ࢖༻

    View Slide

  40. AIRBRAKE-LOGBACK
    ▸ Only set config in logback.xml
    Error logs




    %coloredLevel - %logger - %message%n%xException



    ${config.apikey}
    production - ${config.resource}
    ALL
    https://${yourhost}/notifier_api/v2/notices

    WARN














    MPHCBDLͷઃఆ͚ͩͰ༰қʹ࿈ܞͰ͖Δ

    View Slide

  41. WHAT WE GET FROM PLAY APPS ON DOCKERIZED INFRASTRUCTURE
    ▸ Docker maximizes Scala's advantage
    ▸ Scalable
    ▸ Architecture
    ▸ Development
    %PDLFSʹΑΔΠϯϑϥӡ༻͸4DBMBͷར఺Λ࠷େԽ͢Δ

    View Slide

  42. WE'RE HIRING
    SCALA DEVELOPER!
    LET'S

    View Slide

  43. REFERENCE
    ▸ Play2/ScalaͰυϝΠϯۦಈઃܭΛར༻ͨ͠େن໛WebΞϓϦ
    έʔγϣϯͷεΫϥϜ։ൃͷצॴ 

    http://www.slideshare.net/sifue/developers-summit-2014-
    play2scalaweb
    ▸ AWS Lambda Ͱ PlayʢScalaʣ ͷόονॲཧΛ࣮ߦ͢Δ 

    http://tech.recruit-mp.co.jp/server-side/post-5473/
    ▸ ScalazΛ࢖͓͏ #1 – NET BIZ DIV. TECH BLOG 

    http://tech.recruit-mp.co.jp/server-side/post-2540/

    View Slide