Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

▸ Naoki Ainoya ▸ Server-side / Ops / 
 iOS App developer ABOUT ME

Slide 3

Slide 3 text

ABOUT US ▸ Recruit Marketing Partners Co, Ltd ▸ Our business domain is in
 "Life Event"

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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ίϯςφʹΑͬͯ෼ׂɾૄ݁߹Խ

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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 ཧ༝ͷҰͭ͸%%%ͱ਌࿨ੑ͕ߴ͍͜ͱ

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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/ Ϟφυ΍ؔ਺ܕͷಛ௃Λ׆༻ͯ͠มߋʹڧ͍ίʔυΛॻ͘

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

WHY DO WE USE DOCKER ? ▸ Make a infrastructure immutable
 like a Scala code ▸ Easy to keep an application environment clean ▸ Easy to deploy %PDLFSΛ࢖ͬͯΠϯϑϥ΋Πϛϡʔλϒϧͳӡ༻Ͱ

Slide 15

Slide 15 text

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ʹΑͬͯ։ൃऀ͕ຊ൪؀ڥͷ༷ࢠΛ೺Ѳ͠΍͘͢ͳΔ

Slide 16

Slide 16 text

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 ༰қͳσϓϩΠ͕Մೳ

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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+Λར༻ɺ%#͸ඞཁʹԠͯ͡੾Γସ͑

Slide 19

Slide 19 text

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-ͱ઀ଓ

Slide 20

Slide 20 text

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͸ඞཁͳ࣌ʹ͔͠͠ͳ͍

Slide 21

Slide 21 text

DEPLOYMENT develop feature-A master DEPLOY

Slide 22

Slide 22 text

DEPLOYMENT develop feature-A master Build Docker image
 with
 sbt-native-packager ./activator docker:publish TCUOBUJWFQBDLFSͰ%PDLFSJNBHFΛϏϧυ

Slide 23

Slide 23 text

DEPLOYMENT develop feature-A master Build Docker image
 with
 sbt-native-packager private registry Push docker image ./activator docker:publish ͦͷ··+FOLJOT্͔ΒQSJWBUFSFHJTUSZ΁ΠϝʔδΛQVTI

Slide 24

Slide 24 text

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*Λୟ͍ͯίϯςφΛσϓϩΠ

Slide 25

Slide 25 text

DEPLOYMENT develop feature-A master Build Docker image
 with
 sbt-native-packager private registry Push docker image ECS Upgrade
 services
 via ECS API pull

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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ϑΝΠϧͰࢦఆ

Slide 28

Slide 28 text

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ϑΝΠϧΛ༻ҙ

Slide 29

Slide 29 text

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ϑΝΠϧͰΤϯυϙΠϯτͷ੾Γସ͑΋ߦ͏

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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ϑΝΠϧΛڞ௨Խ͢Δ

Slide 33

Slide 33 text

SCHEDULED JOB ▸ Daily batch job ▸ Daily KPI reporting ▸ Scheduled by Jenkins Executes play application
 by one shot όον࣮ߦʹ͸+FOLJOTΛར༻

Slide 34

Slide 34 text

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Λεέδϡʔϧ࣮ߦ͢Δ

Slide 35

Slide 35 text

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") } ) } ͍ͤͨ͞όονॲཧΛίϚϯυҾ਺Ͱࢦఆ

Slide 36

Slide 36 text

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ͷ๫ൃΛࢭΊΔ

Slide 37

Slide 37 text

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͸σϓϩΠͷલʹ୯ମͰ࣮ߦ͓ͯ͘͠ͷ͕҆৺

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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ͷઃఆ͚ͩͰ༰қʹ࿈ܞͰ͖Δ

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

WE'RE HIRING SCALA DEVELOPER! LET'S

Slide 43

Slide 43 text

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/