Scala Kansai Summit 2017

Fda899b3499ba4d6b2dbc763b3923759?s=47 s_edward
September 09, 2017

Scala Kansai Summit 2017

Scala on Docker

Fda899b3499ba4d6b2dbc763b3923759?s=128

s_edward

September 09, 2017
Tweet

Transcript

  1. Scala on docker 2017೥9݄9೔ ঙ࢘ ॏथ @takesection #scala_ks

  2. AWS Amazon EC2 Amazon ECS AWS Lambda Amazon API Gateway*

    Elastic Load Balancing Amazon Route 53 OS͔ΒΞϓϦέʔγϣϯ·ͰࣗલͰσ ϓϩΠɺӡ༻ DockerΠϝʔδΛ࣮ߦ ίʔυΛ࣮ߦ • ίʔυαΠζͷ੍ݶ • ίʔυͷ࣮ߦ࣌ؒͷ੍ݶ • API GatewayͷλΠϜΞ΢τ࣌ؒͷ੍ݶ
  3. Docker

  4. • ΞϓϦέʔγϣϯΛσʔϞϯͱ࣮ͯ͠ߦ͢ΔΑ͏ͳ࢓૊Έ Λߟ͑ͳ͍͍ͯ͘ • ΞϓϦέʔγϣϯΛDockerΠϝʔδʹ͢Ε͹ɺECSʹݶ ΒͣɺDockerΛಈ͔͢؀ڥ͑͋͞Ε͹खܰʹىಈͯ֬͠ೝ Ͱ͖Δ • ෛՙ͕૿͑ͨͱ͖ʹEC2ΑΓ΋ߴ଎ʹΞϓϦέʔγϣϯͷ ΠϯελϯεΛ૿΍͢͜ͱ͕Ͱ͖Δ

  5. AWS ECS

  6. • Container Instances • Amazon EC2 Instances • Docker daemon

    • Amazon ECS agent
  7. • Clusters • Task Definitions • Tasks • Service •

    Good for long-running applications and services
  8. AWS ECR

  9. • Docker Hub(https://hub.docker.com/)ͷ୅ସ • ࣾ಺ΞϓϦέʔγϣϯͷDockerΠϝʔδΛϗετͰ͖Δ

  10. ಥવͰ͕͢…

  11. None
  12. sbt

  13. • sbt ΛΠϯετʔϧ͓͚ͯ͠͹ɺScalaίϯύΠϥ͸Ϗϧυ ࣌ʹͳ͚Ε͹μ΢ϯϩʔυͯ͘͠ΕΔ • sbt ͸JDK(Java 8)͕ඞཁ • Mac΍Linuxͷ৔߹͸ɺsdkman(http://sdkman.io/)͕࢖͑

    Δ $ sdk install sbt
  14. giter8 https://github.com/scala/scala-seed.g8 $ sbt new scala/scala-seed.g8 A minimal Scala project.

    name [Scala Seed Project]: helloworld Template applied in ./helloworld
  15. σΟϨΫτϦߏ੒ helloworld/ build.sbt project/ build.properties Dependencies.scala src/ main/ scala/ resources/

    test/ scala/ resources/
  16. build.sbt import Dependencies._ lazy val root = (project in file(".")).

    settings( inThisBuild(List( organization := "com.example", scalaVersion := "2.12.3", version := "0.1.0-SNAPSHOT" )), name := "Hello", libraryDependencies += scalaTest % Test )
  17. Dependencies.scala import sbt._ object Dependencies { lazy val scalaTest =

    "org.scalatest" %% "scalatest" % "3.0.3" }
  18. ґଘϥΠϒϥϦ group-id % artifact-id % version ྫ: "com.typesafe.akka" % "akka-http_2.12"

    % “10.0.9" or "com.typesafe.akka" %% “akka-http" % "10.0.9"
  19. build.properties sbt.version=0.13.16

  20. console • sbtͷίϚϯυϓϩϯϓτͰconsoleΛ࣮ߦ͢ΔͱɺScalaͷREPL(Read Eval Print Loop)͕ىಈ͢Δ • ґଘϥΠϒϥϦͷimport΋Ͱ͖ΔͷͰίʔυΛॻ͘લʹࢼ͍ͨ͠ͱ͖͸ศར $ sbt

    > console scala> (1 to 5).foreach(println(_)) scala> :q > exit
  21. sbt-assembly

  22. • ΞϓϦέʔγϣϯͷJarͱґଘϥΠϒϥϦͷJarΛ݁߹͠ ͯɺ࣮ߦՄೳͳJar(fat JAR)Λੜ੒͢Δ

  23. sbt-native-packager

  24. • ScalaΞϓϦέʔγϣϯΛ࣮ߦ͢ΔDockerΠϝʔδΛ࡞ ੒ɺϦϙδτϦ΁ͷpush·Ͱߦ͑Δ • ίϯύΠϧɺDockerfileͷੜ੒Λߦ͏(stage) • Πϝʔδੜ੒ͱϦϙδτϦʹpublish(publishLocal)

  25. build.sbt import Dependencies._ lazy val root = (project in file(“.")).

    enablePlugins(JavaAppPackaging, AshScriptPlugin, DockerPlugin). settings( inThisBuild(List( organization := "com.example", scalaVersion := "2.12.3", version := "0.1.0-SNAPSHOT" )), name := “Hello", dockerBaseImage := "java:8-jdk-alpine", libraryDependencies += scalaTest % Test )
  26. project/plugins.sbt addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" %

    "1.2.0") addSbtPlugin("com.pigumer.sbt.cloud" % "sbt-aws-cloudformation" % "5.0.5")
  27. $ sbt > docker:stage > docker:publishLocal > exit $ docker

    images REPOSITORY TAG IMAGE ID CREATED SIZE hello 0.1.0-SNAPSHOT f27cbbaf1038 6 seconds ago 156MB $ docker run —rm hello:0.1.0-SNAPSHOT hello ※ Docker for Mac Ͱ֬ೝ͍ͯ͠·͢ɻDocker for Mac Ҏ֎͸ະݕূɻ
  28. Akka HTTP

  29. • HTTPͷαʔόʔαΠυɺΫϥΠΞϯταΠυͷ࣮૷ • ؆୯ʹREST APIΛ࡞੒Ͱ͖Δ pathEndOrSingleSlash { get { complete("Hello

    World") } ~ post { entity(as[Foo]) { foo => complete(HttpEntity(ContentTypes.`text/plain(UTF-8)`, foo.name)) } } }
  30. Dependencies.scala import sbt._ object Dependencies { lazy val scalaTest =

    "org.scalatest" %% "scalatest" % "3.0.3" // Akka-HTTP lazy val akkaHttpVersion = "10.0.5" lazy val akkaHttp = "com.typesafe.akka" %% "akka-http" % akkaHttpVersion lazy val helloDeps = Seq( akkaHttp, scalaTest % Test ) }
  31. build.sbt import Dependencies._ lazy val root = (project in file(".")).

    enablePlugins(JavaAppPackaging, AshScriptPlugin, DockerPlugin). settings( inThisBuild(List( organization := "com.github.takesection", scalaVersion := "2.12.3", version := "0.1.0-SNAPSHOT" )), name := "Akka HTTP", dockerBaseImage := "java:8-jdk-alpine", dockerExposedPorts := Seq(8080), libraryDependencies ++= helloDeps )
  32. hello.scala package example import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import

    akka.http.scaladsl.server.Directives._ import scala.concurrent.duration._ class Hello { def createActorSystem = ActorSystem("hello") def route = pathEndOrSingleSlash { complete("Hello World") } ~ path(IntNumber) { id ⇒ complete(s"$id") } }
  33. object Hello extends Hello with App { implicit val system

    = createActorSystem implicit val materializer = ActorMaterializer() implicit val executionContext = system.dispatcher implicit val timeout = 5 seconds val serverBinding = Http().bindAndHandle(handler = route, interface = "0.0.0.0", port = 8080 ) Runtime.getRuntime.addShutdownHook(new Thread { override def run() { serverBinding.flatMap(_.unbind()).onComplete(_ => system.terminate()) } }) }
  34. ࣮ߦ $ sbt > docker:stage > docker:publishLocal > exit $

    docker run -d -p 8080:8080 --rm akka-http:0.1.0-SNAPSHOT $ curl http://localhost:8080/ $ curl http://localhost:8080/123
  35. Akka HTTP • AWS API Gateway΍AWS Lambdaͷ੍ݶΛ௒͑ΔΑ͏ͳ ࣌ؒͷ͔͔Δॲཧ΍ɺෳࡶͳॲཧ͕ඞཁͳREST APIΛ࡞ ੒͍ͨ͠৔߹ʹ޲͍͍ͯΔ

    • OAuth Token΍CORSʹରԠ͢ΔͨΊͷϥΠϒϥϦ͕OSS Ͱެ։͞Ε͍ͯΔ
  36. akka-stream

  37. • Akka HTTP͸ɺakka-actorͱakka-streamͷ্ʹ࡞ΕΒͯ ͍Δ • Stream͸ɺSource͔ΒೖͬͯɺFlowΛ௨ΓɺSinkͰऴΘ Δ

  38. Dependencies.scala import sbt._ object Dependencies { val akkaStreamVersion = "2.5.1"

    lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.0.3" lazy val helloDeps = Seq( scalaTest % Test, "com.typesafe.akka" %% "akka-stream" % akkaStreamVersion ) }
  39. build.sbt import Dependencies._ lazy val root = (project in file(".")).

    enablePlugins(JavaAppPackaging, AshScriptPlugin, DockerPlugin). settings( inThisBuild(List( organization := "com.github.takesection", scalaVersion := "2.12.3", version := "0.1.0-SNAPSHOT" )), name := "Akka Stream", dockerBaseImage := "java:8-jdk-alpine", libraryDependencies ++= helloDeps )
  40. hello.scala package example import akka.actor.ActorSystem import akka.stream.ActorMaterializer import akka.stream.scaladsl._ import

    scala.concurrent.Await import scala.concurrent.duration._ object Hello extends App { implicit val system = ActorSystem("Hello") implicit val materializer = ActorMaterializer() implicit val executionContext = system.dispatcher val flow = Source(1 to 5).via(Flow[Int].map(_ * 2)).runWith(Sink.seq[Int]) val results = Await.result(flow, 5 seconds) results.foreach(println(_)) sys.exit }
  41. ࣮ߦ $ sbt > docker:stage > docker:publishLocal > exit $

    docker run --rm akka-stream:0.1.0-SNAPSHOT
  42. akka-stream • Kinesis΍SQSͷϝοηʔδͷΑ͏ͳඇಉظͷΠϕϯτΛτϦΨʔʹॲཧ Λߦ͏Α͏ͳΞϓϦέʔγϣϯʹ޲͍ͯΔ • alpakka( http://developer.lightbend.com/docs/alpakka/current/sqs.html ) Amazon SQS

    Amazon Kinesis Amazon RDS Flow Source Flow Sink
  43. Scala

  44. • Option • Some͔NoneͱͳΔ Option(null) match { case Some(a) 㱺

    ??? case None 㱺 println("NONE") }
  45. • Try • Tryͷ݁Ռ͸ɺSuccess͔FailureͱͳΔ • Either • Eitherͷ݁Ռ͸ɺLeft͔RightͱͳΔ • ίϨΫγϣϯҎ֎ͨͱ͑͹Option,

    Try, Either, Future౳Ͱ ΋map΍flatMap౳͕࢖͑Δ
  46. • head Seq(3,2,1).head Seq.empty[Int].headOption • intersect΍diffͷΑ͏ͳू߹ԋࢉ (1 to 5).intersect(List(2, 4,

    7)) (1.to(5)).diff(List(2, 3))
  47. • ύλʔϯϚον Seq(Some(1), Some(2), None).foreach { case Some(n) 㱺 println(n.toString)

    case None 㱺 println("NONE") }
  48. • @tailrec @tailrec private def loop(list: Seq[Int]): Unit = list

    match { case head +: tails 㱺 println(head) loop(tails) case Nil 㱺 () }
  49. None
  50. None
  51. None
  52. • Deploying Amazon EC2 Container Service (ECS) - Simple Cloud

    Hosting on AWS( https://youtu.be/1wLMLwjCqN4 ) • Amazon ECS: Autoscaling for Containers( https:// youtu.be/YEvU6uIckDc )
  53. https://github.com/takesection/scala-kansai-summit-2017