Warum wir für Microservices auf Spring Boot setzen
Zurück zum Blog

Warum wir für Microservices auf Spring Boot setzen

5 Min. Lesezeit
Lesen auf English

Der Monolith wird zum Problem

Wer in den letzten Jahren Enterprise-Software entwickelt hat, kennt das Muster: Eine Anwendung startet als überschaubares Projekt, wächst über Monate und Jahre, und irgendwann hat man einen Monolithen, den niemand mehr vollständig überblickt. Deployments werden zum Risiko, Build-Zeiten explodieren, und Teams blockieren sich gegenseitig, weil alle am selben Artefakt arbeiten.

Genau das haben wir in mehreren Kundenprojekten erlebt. Der klassische Java-EE-Ansatz mit WAR-Deployments auf einem Application Server funktioniert -- bis er es nicht mehr tut. Spätestens wenn ein Team aus mehr als fünf Entwicklern besteht und die Anwendung mehrere fachliche Domänen abdeckt, wird der Monolith zum Flaschenhals.

Microservices sind hier kein Allheilmittel, aber sie lösen einige dieser Probleme sehr elegant: unabhängige Deployments, klare Verantwortlichkeiten, technologische Freiheit pro Service. Die Frage war für uns nicht ob, sondern wie.

Warum Spring Boot?

Nach Evaluierung verschiedener Frameworks -- darunter Dropwizard, Vert.x und reine Java-EE-Ansätze mit WildFly Swarm -- sind wir bei Spring Boot gelandet. Die Gründe dafür sind vielschichtig.

Auto-Configuration: Weniger Boilerplate, mehr Produktivität

Spring Boot analysiert den Classpath und konfiguriert Beans automatisch. Wer eine H2-Datenbank im Classpath hat, bekommt eine DataSource. Wer Spring MVC einbindet, bekommt einen eingebetteten Tomcat. Das klingt trivial, spart in der Praxis aber enorm viel Zeit, die man sonst mit XML-Konfiguration oder manuellen Bean-Definitionen verbringt.

Eine lauffähige Anwendung lässt sich in wenigen Minuten aufsetzen:

@SpringBootApplication
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

Das ist der gesamte Code, den man braucht, um einen Service zu starten. Kein web.xml, kein Application-Server-Setup, kein Deployment-Descriptor.

Eingebetteter Server: Ein JAR, ein Prozess

In der Microservice-Welt ist die Deployment-Einheit entscheidend. Spring Boot baut ein sogenanntes Fat JAR -- eine einzelne JAR-Datei, die den eingebetteten Tomcat (oder Jetty, oder Undertow) bereits enthält. Das bedeutet: java -jar order-service.jar und der Service läuft.

Das vereinfacht nicht nur das Deployment, sondern auch die Container-Strategie. Ein Dockerfile für einen Spring-Boot-Service ist denkbar einfach:

FROM openjdk:8-jre-alpine
COPY target/order-service.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

In Kombination mit Docker wird jeder Service zu einem eigenständigen Container, der unabhängig skaliert und deployed werden kann.

Opinionated Defaults: Konvention statt Konfiguration

Spring Boot trifft bewusste Entscheidungen. Jackson für JSON-Serialisierung, Logback für Logging, Tomcat als eingebetteter Server. Man kann alles überschreiben, muss es aber nicht. Für Teams, die mehrere Services parallel entwickeln, ist das Gold wert: Jeder Service verhält sich gleich, ohne dass man einen eigenen Framework-Stack zusammenstecken muss.

Die application.properties bzw. application.yml bieten einen zentralen Ort für die gesamte Konfiguration. Umgebungsspezifische Einstellungen lassen sich über Profile (spring.profiles.active) sauber trennen -- ein Muster, das hervorragend zu einer Microservice-Architektur passt.

Spring Cloud: Das Ökosystem für verteilte Systeme

Microservices bringen eigene Herausforderungen mit: Service Discovery, Load Balancing, zentrale Konfiguration, Circuit Breaker. Hier kommt Spring Cloud ins Spiel, das eng auf Spring Boot aufbaut und viele dieser Themen adressiert.

Besonders die Integration mit Netflix OSS hat uns überzeugt:

  • Eureka für Service Discovery -- jeder Service registriert sich automatisch und kann andere Services über ihren Namen finden.
  • Ribbon für clientseitiges Load Balancing -- Anfragen werden intelligent auf verfügbare Instanzen verteilt.
  • Hystrix als Circuit Breaker -- wenn ein nachgelagerter Service ausfällt, greift ein Fallback, statt die gesamte Aufrufkette zu blockieren.
  • Zuul als API Gateway -- ein zentraler Einstiegspunkt, der Routing, Filterung und Authentifizierung übernimmt.

Alle diese Komponenten lassen sich mit wenigen Annotationen und minimaler Konfiguration in einen Spring-Boot-Service integrieren. Das senkt die Einstiegshürde erheblich.

REST-APIs mit Spring Boot: Ein Praxisbeispiel

Ein typischer Microservice bei uns exponiert eine REST-API. Mit Spring Boot sieht ein einfacher Controller so aus:

@RestController
@RequestMapping("/api/orders")
public class OrderController {

    private final OrderService orderService;

    @Autowired
    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<Order> getOrder(@PathVariable Long id) {
        return orderService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    public ResponseEntity<Order> createOrder(@RequestBody @Valid Order order) {
        Order created = orderService.create(order);
        URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(created.getId())
                .toUri();
        return ResponseEntity.created(location).body(created);
    }
}

Content Negotiation, Fehlerbehandlung und JSON-Serialisierung funktionieren out of the box. Wer Spring Data JPA einbindet, bekommt dazu ein Repository-Pattern, das den Datenbankzugriff auf wenige Zeilen reduziert. Das erlaubt es uns, neue Services innerhalb von Stunden produktionsreif aufzusetzen -- nicht Tagen.

Die Starter-POMs als Baukasten

Ein oft unterschätzter Vorteil sind die Spring-Boot-Starter-POMs. Statt sich durch Dependency-Konflikte zu kämpfen, zieht man einen Starter rein und bekommt ein abgestimmtes Set an Bibliotheken:

  • spring-boot-starter-web für REST-Services
  • spring-boot-starter-data-jpa für Datenbankzugriff
  • spring-boot-starter-security für Authentifizierung und Autorisierung
  • spring-boot-starter-actuator für Health Checks und Metriken

Gerade der Actuator ist für Microservices unverzichtbar. Er liefert Endpunkte für Health Checks, die ein Orchestrator wie Docker Swarm oder Kubernetes nutzen kann, um den Zustand eines Services zu überwachen.

Was man beachten sollte

Microservices mit Spring Boot sind kein Selbstläufer. Die Komplexität verschiebt sich vom Code in die Infrastruktur. Man braucht eine solide CI/CD-Pipeline, ein durchdachtes Logging-Konzept (wir setzen auf den ELK-Stack) und ein Monitoring, das über einzelne Services hinausgeht.

Auch die Kommunikation zwischen Services will gut geplant sein. Synchrone REST-Calls erzeugen Abhängigkeiten; asynchrone Kommunikation über einen Message Broker wie RabbitMQ kann hier Abhilfe schaffen, erhöht aber die Komplexität.

Wer mit Microservices startet, sollte klein anfangen. Nicht gleich 20 Services aufsetzen, sondern mit zwei oder drei beginnen, die Infrastruktur aufbauen und Erfahrung sammeln.

Ausblick

Spring Boot hat sich für uns als das produktivste Framework für Microservices in der Java-Welt etabliert. Die Kombination aus schnellem Einstieg, durchdachten Defaults und dem mächtigen Spring-Cloud-Ökosystem macht es zur ersten Wahl für neue Projekte.

Mit der zunehmenden Verbreitung von Docker und Container-Orchestrierungsplattformen wird dieser Ansatz in den kommenden Jahren noch relevanter werden. Wir beobachten gespannt die Entwicklung im Bereich Container-Orchestrierung und sind überzeugt, dass Spring Boot hier weiter an Bedeutung gewinnen wird.

In zukünftigen Artikeln werden wir tiefer in einzelne Aspekte eintauchen: Service Discovery mit Eureka, Konfigurationsmanagement mit Spring Cloud Config und das Thema Monitoring in einer verteilten Architektur.

Teilen

Patrick Hütter

Geschrieben von

Patrick Hütter

Gründer & Software-Architekt

Softwarearchitekt, Ingenieur und Unternehmer. Patrick baut seit über einem Jahrzehnt Produkte und Plattformen — von Enterprise-Backends über Cloud-Native-Infrastruktur bis hin zu KI-gestützten Anwendungen. Als Gründer von encircle360 verbindet er technische Tiefe mit unternehmerischem Denken und treibt Open-Source-Projekte voran, die echten Impact haben.