Ich nehme derzeit an einer Akademie zum Java Fullstack Software Engineer teil. In den kommenden Wochen möchte ich hier meine Mitschrift, so gut es geht, aufzeichnen und mitteilen. Hier ist das, was ich vom ersten Tag in Block 12 (es gab keinen Block 11, der wurde mit in 10 integriert) gelernt und behalten habe:
Microservices & Design
Wiederholung: Die Welt zum Web wird durch den Controller, die Welt zur Datenbank durch das Repository abgebildet (Die Kreis-Kringel stehen für Objekte):

Beispiel einer Microservice Struktur:
In den folgenden Tagen wollen wir folgendes (in einer Testumgebung und nur rudimentär) bauen:
Als Datenbankpool für unsere Bücher wollen wir eine mySQL-Maria-DB verwenden. Diese lauscht auf den Port 3306.
Diese Bücher wollen wir im Web anbieten. Z.B. durch Javascript, Angular, React (Apache-Server oder NGNX) mit Port 80 oder 443.
Als Logik bauen wir BookServices (Spring) mit Port 8081, welches via DAO auf die Maria-DB zugreift.
Die Customer DB ist in unserem Beispiel eine Mongo-DB (noSQL), Port 27017.
Die Customer Services (Spring), Port 8084, werden redundant ausgelegt.
Wenn man aus dem Internet auf die Services zugreifen will, braucht man einen Security Proxy als Einstiegspunkt. Z.B. das Produkt "Zuul". Damit sind zwei Türen auf, der Webservice (Port 80) als Start-Seite und der Security-Proxy (8080), für alle nachgelagerten Services.
Der Registrierungsserver ("Eureka", eine Art DNS Service) an dem sich die verschiedenen Dienste einmalig registrieren müssen, dient um die Sicherheit im Intranet zu erhöhen.
Ein Benutzer, der ein Buch ausleihen möchte, landet zuerst auf dem Webserver. Dieser fragt (über den Security-Server) den Eureaka-Server, wo er den Customer-Service findet. Der schickt die Anfrage weiter an den Load-Balancer.
Der Rent-Service sorgt für die Ausleih-Logik mit PDF-Generator, QR-Code-Generator, UUID-Generator als Hilfsservices.

Docker
Ein Image ist eine Art Template (zweidimensional). Der Container ist die Laufzeitumgebung (dreidimensional). Für die meisten Services brauche ich ein Image und einen Container. Bei dem Customerservice haben wir ein Image aber mehrere Container.

Wir haben Zugang zu einem Linux-Server erhalten und legen dort den Ordner docker-space an:

So soll es irgendwann mal aussehen:

[linux@essen2-0005 docker-space]$ docker -v Docker version 1.13.1, build 7f2769b/1.13.1
Wir hatten schon ein paar Images vorinstalliert:
[linux@essen2-0005 docker-space]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/mariadb latest a9e108e8ee8a 2 years ago 356 MB docker.io/centos latest 0f3e07c0138f 2 years ago 220 MB docker.io/fedora latest 9eff96f4c827 2 years ago 248 MB docker.io/hello-world latest fce289e99eb9 3 years ago 1.84 kB [linux@essen2-0005 docker-space]$
Unterschied zwischen Containern und virtuellen Maschinen:

Bei https://hub.docker.com kann man sich fertige Docker-Images runterladen:

Den Container starten geht mit "docker run":

"docker ps -all" zeigt alle, auch die beendeten Container an:

Auszüge aus "poster-docker.pdf":





Wir laden die neueste openjdk-Docker Version runter. Es werden im Hintergrund weitere Images runter geladen:

Wir starten eine interaktive Ubuntu bash. Das nichtvorhandene Ubuntu wir automatisch herunter geladen:

Openjdk bringt auch ein minimales Linux mit. Wir können es interaktiv starten mit:
docker run -it openjdk bash

Wenn einem die Version nicht gefällt, kann man auch eine ältere wählen:

Sollte es später einen neuen Security Patch geben, dann wiederholt man den Befehl einfach noch mal.
Zum Löschen eines Images müssen zuerst die alten Containerreste entfernt werden:

Docker Umfeld
Das Dockerfile führt ein bestehendes Image und ein Java Springboot Projekt zusammen und erstellt ein neues Image.
Das Image wird in einer Regstry abgelegt und registriert.
Daraus wird ein Container gebaut:

Wir kopieren das Kehrwertservice-Jar-File mit WinSCP in unseren Linux Server:

Wir erstellen eine Datei mit dem Namen "Dockerfile" im Readme-Ordner unseres Java-Projektes:

Expose gibt den oder die Portnummern an, die intern zur Verfügung gestellt werden. In unserem Beispiel steht in der application.properties server.port=8080. Also muss dieser Port auch im Docker bekannt gegeben (exposed) werden. Welchen Port der Docker Container später von außen erhält, wird über den run-Befehl mitgegeben.
Wir kopieren diese Dockerfile-Datei in den Linux-Ordner:

Wir erstellen zu Dokumantationszwecken im readme-Ordner unseres Java-Pojektes eine leere Datei "docker-doit.txt" und schreiben dort folgenden Inhalt rein. Das sind die Spielregeln um das neue Dockerimage zu erstellen:

Wir bauen das Dockerimage:
Docker build --tag kws-v01.img . (Auszuführen in dem Verzeichnis, wo das Jarfile und das Dockerfile liegt)

Wir starten den Docker Container:

docker run -p8888:8080 --name kehrwertservice kws-v01.img (der interne Port 8080 wird nach außen mit Port 8888 übergeben):

Wir testen, ob der Service erreichbar ist:
curl -v -X GET http://localhost:8888/kehrwertservice/kehrwert?zahl=4 (Ergebnis ist 0.25 links unten):

"docker run" ist nur dazu da um aus einem Image den ersten initialen Container zu bauen. Danach starten wir die Container mit einem "docker start":

Um in die Maschine (laufenden Container) rein zu kommen geben wir ein:
docker exec -it kehrwertservice

-------------------------------------------------
Disclaimer
Alles was ich mitschrieb und verstanden habe ist ohne Gewähr. Die Bilder stammen teilweise aus dem Internet und wir haben keine Urheberansprüche darauf.
Besten Dank an unseren sehr empfehlenswerten
Trainer: Hans-Joachim Blanke blanke@4point.de

In den nächsten Tagen geht es weiter, so: stay tuned!
Achim Mertens