Dieses Projekt ist für das Labor Verteilte Systeme der Hochschule Karlsruhe - Technik und Wirtschaft der Informatik Fakultät.
Dieses Projekt benutzt den Spring Cloud Solution Stack um eine Microservice Landschaft zu erstellen, die einen Web Shop abbildet. Dabei erweitert bzw. verändert sie eine existierende monolithische Web-Anwendung und führt zusätzliche Microservice-Komponenten ein, welche von Spring Cloud angeboten werden.
Die Spring Cloud Microservice Applications sind als einzelne Docker-Container realisiert, welche mit dem fabric8io docker-maven-plugin erstellt werden.
Das Projekt enthält neben den fachlichen Microservices, welche für einen Web Shop notwendig sind, die folgenden Komponenten:
- Einen Config-Service mit Spring Cloud Config
- Einen Discovery-Service mit Spring Cloud Netflix Eureka
- Ein API-Gateway mit Spring Cloud Netflix Zuul
- Einen OAuth2-Service mit Spring Cloud Security
- Ein Hystrix Dashboard, Hystrix Integration für Microservices und einen Turbine Server mit Spring Cloud Netflix Hystrix
- ...
Um das Projekt auszuführen, benötigt man:
- Maven
- Docker
- Docker-Compose
- Als IDE eignet sich bspw. Spring Tool Suite
Um die Docker Container mit den enthaltenen Microservices zu erstellen, müssen folgende Vorbereitungen getroffen werden:
- In der Parent-POM im Projekt-Ordner muss die Property
<docker.user>[Benutzername]</docker.user>
mit dem eigenen Docker Hub Account gesetzt werden. - Außerdem müssen die Umgebungsvariablen
DOCKER_PWD
undCONFIG_SERVICE_PASSWORD
gesetzt werden. - In der
docker-compose.yml
müssen die Namen der Images auf den Wert von<docker.user>
geändert werden.
Als nächstes müssen die Container mit Maven gebildet werden. Hierfür sollte der Befehl
mvn clean package docker:build
ausgeführt werden.
Um die Container Images auf Docker Hub zu pushen muss
mvn clean package docker:build docker:push
verwendet werden.
Schließlich muss im Projekt-Verzeichnis noch
docker-compose up -d
ausgeführt werden, um die in der docker-compose.yml
aufgelisteten Container zu starten.
In der Spring Tool Suite (STS) kann ein neuer Microservice bzw. ein Modul zum Parent Projekt hinzugefügt werden, in dem man:
- einen Rechtsklick auf das Parent-Projekt macht
- und dann
New --> Project
wählt. - Es öffnet sich ein Auswahlfenster. Hier wählt man Maven --> Maven Module
- Man klickt auf
Next
, gibt einen Namen für das Module ein - und setzt einen Haken bei
Create a simple project (skip archetype selection)
. - Danach befolgt man den Wizard weiter, setzt möglicherweise noch einen Namen und eine Beschreibung
- und das Modul wird erstellt.
Dem Projekt liegt ein MySQL Docker-Container bei, der wie folgt in der docker-compose.yml
definiert ist:
mysqldb:
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: webshop
MYSQL_USER: shop
MYSQL_PASSWORD: shop
image: mysql
restart: always
ports:
- 3307:3306
logging:
options:
max-size: 10m
max-file: '10'
Dieser wird im Container-Netzwerk über den Standardport 3306
angesprochen. Vom Docker-Host kann man über 3307
auf die MySQL-Datenbank zugreifen.
Wenn man nun einen Core-Service erstellen will, der auf den MySQL-Container zugreift kann man den product-core-service
als Referenz nehmen.
In der product-core-service.yml
im shared
Ordner des config-service
ist die Konfiguration definiert. Hier ein Ausschnitt:
spring:
datasource:
url: jdbc:mysql://mysqldb:3306/webshop
username: shop
password: shop
driver-class-name: com.mysql.jdbc.Driver
jpa:
show-sql: true
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
ddl-auto: validate
Mit dieser Konfiguration kann der Core-Service als Container auf die Datenbank zugreifen für den test/resources
Ordner sollte eine zusätzliche Testkonfiguration angelegt werden. Diese wird in der application.yml
hinterlegt und sieht wie folgt aus:
spring:
datasource:
url: jdbc:mysql://localhost:3307/webshop
username: shop
password: shop
driver-class-name: com.mysql.jdbc.Driver
jpa:
show-sql: true
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
ddl-auto: validate
Hier wird der MySQL-Container vom Docker-Host aus angesprochen. Auch hier ist eine Beispielkonfiguration im product-core-service
hinterlegt.
Damit die Datenbankanbindung funktioniert, sollte der Core-Service außerdem folgende Dependencies enthalten:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
Wenn man die Datenbank mit Testdaten befüllen möchte bietet es sich an, in main/resources
, eine import.sql
anzulegen. Dieses Skript wird beim Starten des Core-Services ausgeführt. import.sql
enthält hierbei normalerweise Tabelleneinträge. Zum Beispiel im product-core-service
:
Insert INTO `product` VALUES(1, 1,'Leckeres Toastbrot', 'Toast', 0.49);
Danach kann Spring Data JPA genutzt werden. Datenbanktabellen werden hier objektrelational auf Objekte gemappt. Siehe hierzu die Product.java
Klasse des product-core-service
. Um Datenbank-Operationen auszuführen kann ein Repository-Interface analog zu ProductRepository.java
erstellt werden.
Die einzelnen Microservices sind wie folgt zu erreichen:
- Das Spring Eureka Dashboard ist unter
http://localhost:8761
zu erreichen. - Das API-Gateway ist unter
http://localhost:4000
zu erreichen. Alle Mappings können unterhttp://localhost:4000/routes
eingesehen werden. - Das Hystrix Dashboard ist unter
http://localhost:4000/hystrix
zu erreichen. - Der Turbine Stream ist unter
http://localhost:4000/turbine.stream
zu erreichen.