de Miguel Lopez

Cum să ancorați o aplicație HTTP Scala și Akka – modul simplu

Cum sa ancorati o aplicatie HTTP Scala si Akka

Utilizarea Docker este o dată în zilele noastre. În acest tutorial vom afla cum să învățăm să ancorăm aplicațiile HTTP Scala și Akka fără chiar creând un fișier Docker noi înșine.

În scopul acestui tutorial, presupunem că Docker este deja instalat pe aparat. Dacă nu este, vă rugăm să urmați documentație oficială.

Pentru a automatiza crearea fișierului Docker pentru proiectul nostru, vom folosi fișierul sbt-native-packager conecteaza.

Puteți utiliza orice proiect Scala sau Akka HTTP pentru acest tutorial. Vom folosi următoarele repertoriu, nu ezitați să o clonați și asigurați-vă că ați achitat sucursala 6.5-testing-directives.

Adăugarea pluginului

Mai întâi, trebuie să adăugăm pluginul la proiectul nostru în project/plugins.sbt fişier. Dacă fișierul nu există, trebuie să-l creăm și apoi să adăugăm următoarea linie:

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.6")

Apoi, trebuie să activăm pluginul în build.sbt fişier. Adăugați următoarea linie în partea de sus:

enablePlugins(JavaAppPackaging)

Activarea acestui plugin ne permite, de asemenea, să creăm un executabil pentru aplicația noastră. Alerga sbt stage în directorul rădăcină al proiectului.

Acum putem executa aplicația noastră rulând ./target/universal/stage/bin/akkahttp-quickstart. Ar trebui să vedeți un Success! mesaj. Dacă trimiteți o solicitare GET către localhost:9000/todos veți primi câteva.

Cum sa ancorati o aplicatie HTTP Scala si Akka

Dockerising aplicația noastră

Este timpul să începem să ne jucăm cu Docker.

Să începem prin generarea fișierului Docker pentru aplicația noastră. Alerga sbt docker:stage, apoi fugi cat target/docker/stage/Dockerfile pentru a vedea conținutul acestuia:

FROM openjdk:latestWORKDIR /opt/dockerADD --chown=daemon:daemon opt /optUSER daemonENTRYPOINT ["/opt/docker/bin/akkahttp-quickstart"]CMD []

Este destul de simplu. Se termină prin executarea unui binar similar cu cel pe care l-am generat și l-am rulat mai devreme.

Putem construi o imagine Docker folosind acel Dockerfile manual, dar există un mod mai convenabil de a face acest lucru. Să fugim sbt docker:publishLocal. După cum sugerează și numele său, va publica o imagine Docker a aplicației noastre în registrul nostru local.

Alerga docker images și ar trebui să vedeți următoarea intrare:

REPOSITORY            TAG     IMAGE ID       CREATED          SIZEakkahttp-quickstart   0.1     d03732dd0854   42 seconds ago   774MB

Acum putem rula aplicația folosind Docker.

Alerga docker run akkahttp-quickstart:0.1, ar trebui să vedeți Success! mesaj încă o dată.

Dar de data aceasta, dacă încercăm să ne interogăm aplicația, vom primi o eroare:

1612020007 163 Cum sa ancorati o aplicatie HTTP Scala si Akka

Să fugim docker ps pentru a obține câteva informații despre procesul Docker care rulează (ieșire prescurtată):

CONTAINER ID     IMAGE                       PORTS            NAMES9746162d4723     akkahttp-quickstart:0.1                      serene_agnesi

După cum putem vedea, nu există porturi expuse, deci nu există nicio modalitate de a comunica cu aplicația noastră.

Aplicațiile din Docker rulează în mod implicit în rețeaua lor. Există mai multe modalități de a permite comunicarea între procesele Docker și mașina gazdă. Cea mai simplă modalitate este de a expune un port.

Opriți aplicația care rulează, fie lovind Ctrl-C sau alergând docker stop $CONTAINER_ID.

De data aceasta când îl rulăm, vom expune și portul respectiv:

docker run -p 9000:9000 akkahttp-quickstart:0.1

Acum putem interoga aplicația noastră ancorată:

1612020007 886 Cum sa ancorati o aplicatie HTTP Scala si Akka

Personalizarea configurării noastre

Există mai multe lucruri pe care am putea dori să le facem cu configurarea curentă pe care o avem:

  • Ce se întâmplă dacă dorim un nume de imagine diferit?
  • Ce se întâmplă dacă vrem să folosim un alt port?
  • Putem avea o imagine mai ușoară?

Să explorăm aceste cazuri de utilizare obișnuite.

Schimbarea numelui imaginii

Dacă ne uităm la documentația oficială a pluginului, vedem că există o serie de opțiuni pe care le putem schimba.

Citiți-o și vedeți ce altceva puteți personaliza.

Pentru a schimba numele imaginii putem modifica fișierul packageName proprietate în build.sbt fișier, adăugați următoarea linie după scalaVersion proprietate:

packageName in Docker := "dockerised-akka-http"

Să publicăm din nou imaginea. Alerga sbt docker:publishLocal. Putem verifica dacă avem o nouă imagine rulând docker images:

REPOSITORY            TAG   IMAGE ID       CREATED          SIZE akkahttp-quickstart   0.1   d03732dd0854   42 minutes ago   774MB dockerised-akka-http  0.1   d03732dd0854   42 minutes ago   774MB

Acum avem două imagini, cea originală și cea nouă. Minunat!

Schimbarea portului

Nu putem schimba portul pe care îl ascultă aplicația noastră fără a face modificări de cod. Portul este codat în aplicația noastră. În mod ideal, l-am citi dintr-o variabilă de mediu și poate avea una ca implicită.

Dar este în regulă. Deoarece aplicația noastră rulează într-o altă rețea, putem să mapăm un port diferit de portul intern 9000.

Când specificăm steagul -p 9000:9000 spunem că portul 9000 din mașina gazdă va mapa la portul 9000 din rețeaua procesului nostru. Să încercăm să schimbăm asta.

Alerga docker run -p 5000:9000 dockerised-akka-http:0.1 pentru a rula noua noastră imagine cu un alt port.

Putem interoga todos pentru a vă asigura că funcționează conform așteptărilor:

1612020008 657 Cum sa ancorati o aplicatie HTTP Scala si Akka

Făcând imaginea noastră mai ușoară

Pentru ultimul nostru experiment, vom încerca să ne ușurăm imaginea. În acest moment folosește peste 700 MB.

În primul rând, să mărim versiunea, astfel încât să obținem o etichetă diferită și să le putem compara. Apoi adauga dockerBaseImage := "openjdk:8-jre-alpine" deasupra unde schimbăm packageName . Al nostru build.sbt acum arată ca:

enablePlugins(JavaAppPackaging)
name := "akkahttp-quickstart"version := "0.2"scalaVersion := "2.12.6"
dockerBaseImage := "openjdk:8-jre-alpine"packageName in Docker := "dockerised-akka-http"
val akkaVersion = "2.5.13"val akkaHttpVersion = "10.1.3"val circeVersion = "0.9.3"
libraryDependencies ++= Seq(  "com.typesafe.akka" %% "akka-actor" % akkaVersion,  "com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-stream" % akkaVersion,  "com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-http" % akkaHttpVersion,  "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test,  "io.circe" %% "circe-core" % circeVersion,  "io.circe" %% "circe-generic" % circeVersion,  "io.circe" %% "circe-parser" % circeVersion,  "de.heikoseeberger" %% "akka-http-circe" % "1.21.0",  "org.scalatest" %% "scalatest" % "3.0.5" % Test)

Folosim o etichetă diferită a openjdk imagine de bază pentru a specifica pe care vrem să o folosim alpine, care este o distribuție Linux ușoară.

Publică imaginea rulând sbt docker:publishLocal. Obțineți imaginile cu docker images . Putem vedea că imaginea este mai deschisă acum:

REPOSITORY             TAG   IMAGE ID       CREATED          SIZE dockerised-akka-http   0.2   4688366e70bb   32 seconds ago   119MB akkahttp-quickstart    0.1   d03732dd0854   2 hours ago      774MBdockerised-akka-http   0.1   d03732dd0854   2 hours ago      774MB

Să ne asigurăm că funcționează în continuare.

Alerga docker run -p 5000:9000 dockerised-akka-http:0.2, luând în considerare numărul etichetei. Nu funcționează, anunțul primind următoarea eroare:

env: can't execute 'bash': No such file or directory

Se pare că aplicația noastră ancorată are nevoie bash a alerga. Citind documentația pluginului, putem spune că generează un script bash care execută aplicația noastră.

Deci, să instalăm bash în imaginea noastră și să încercăm din nou.

Adăugați următoarele rânduri mai jos, unde schimbăm packageName în a noastră build.sbt fişier:

import com.typesafe.sbt.packager.docker._dockerCommands ++= Seq(  Cmd("USER", "root"),  ExecCmd("RUN", "apk", "add", "--no-cache", "bash"))

Adăugăm câteva comenzi suplimentare la Dockefile. Schimbăm utilizatorul în root pentru a instala pachetul, apoi vom instala bash.

Să încercăm din nou să rulăm aplicația, docker run -p 5000:9000 dockerised-akka-http:0.2. Și funcționează acum, minunat!

Dacă verificăm din nou imaginile, alpin-una bazată este ceva mai mare, ca 10 MB. Asta nu este nimic în comparație cu cei aproximativ 770 MB din ceilalți.

Se instalează bash în alpin nu este cel mai rău lucru din lume. Unii oameni ajung să-l adauge oricum datorită preferințelor lor și pentru depanare.

Generarea unui executabil compatibil cu Ash

Instalarea bash-ului pe imaginea noastră este o soluție. Să folosim un plugin suplimentar pentru a genera un executabil care este compatibil cu Alpine. Mulțumită Vânzător Muki pentru că ne-ați informat despre această soluție!

In conformitate cu documentație oficială, trebuie să activăm pluginul suplimentar AshScriptPlugin.

Modificați fișierul build.sbt pentru a activa ambele pluginuri și pentru a elimina soluția anterioară:

enablePlugins(JavaAppPackaging, AshScriptPlugin)
name := "akkahttp-quickstart"version := "0.3"scalaVersion := "2.12.6"
dockerBaseImage := "openjdk:8-jre-alpine"packageName in Docker := "dockerised-akka-http"
val akkaVersion = "2.5.13"val akkaHttpVersion = "10.1.3"val circeVersion = "0.9.3"
libraryDependencies ++= Seq(  "com.typesafe.akka" %% "akka-actor" % akkaVersion,  "com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-stream" % akkaVersion,  "com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,  "com.typesafe.akka" %% "akka-http" % akkaHttpVersion,  "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test,
  "io.circe" %% "circe-core" % circeVersion,  "io.circe" %% "circe-generic" % circeVersion,  "io.circe" %% "circe-parser" % circeVersion,  "de.heikoseeberger" %% "akka-http-circe" % "1.21.0",
  "org.scalatest" %% "scalatest" % "3.0.5" % Test)

De asemenea, am mărit versiunea, astfel încât să o putem compara și să evităm să o anulăm pe cea precedentă.

Alerga sbt docker:publishLocal, și apoi docker run dockerised-akka-http:0.3.

Ar trebui să vedeți mesajul de succes și, dacă interogați pentru toate, ar trebui să le vedeți și ele. Grozav!

Concluzie

În acest tutorial am ancorat o aplicație HTTP Scala și Akka. Nu s-a făcut nimic special pentru această aplicație, ceea ce înseamnă că setarea va funcționa cam așa cum este.

Apoi ne-am uitat la modul de realizare a unor cazuri de utilizare obișnuite, personalizând fișierul Docker prin intermediul pluginului.

Am reușit chiar să reducem dimensiunea imaginii de aproape șapte ori!

Uimitor, nu-i așa?

Dacă ți-a plăcut acest tutorial și vrei să înveți cum să construiești un API pentru o aplicație todo, consultați nou liber curs! ???

Publicat inițial la www.codemunity.io.