Start / Cheat Sheets

Cheat Sheet

Quarkus für Microservices — Cheat Sheet

Stand: · Quarkus-Training

QuarkusMicroservicesMicroProfileNative Image

Der Spickzettel zum Quarkus-Training — von der ersten Anwendung bis zum Native Image. Schwerpunkt sind die Entscheidungen, die man beim Bauen eines Dienstes trifft, und die Stellen, an denen es später hakt.

Ausführungs- und Build-Varianten

ModusStart / SpeicherEinsatz
JVM-Mode~1 s / moderatEntwicklung, klassische Deployments
AOT-Caching (Leyden)schneller / moderatJVM-Start beschleunigen (Preview)
Native (GraalVM)~0,01 s / minimalServerless, Scale-to-zero
Build-VarianteStartzeitSpeicherBuild-Dauer
Fast-JAR~1 smoderatkurz
Native~0,01 sminimallang
Leyden-AOTschnellmoderatmittel
quarkus create app de.hco:kurs-api --extension=rest,rest-jackson
quarkus dev                 # r = Tests, d = Dev UI, q = beenden
quarkus build --native
quarkus image build docker

„Native immer besser” stimmt nicht: längere Builds, GraalVM-Fallstricke, und für die Entwicklung ist der JVM-Mode völlig ausreichend. Native kommt am Ende.

Modul: Grundlagen & erste Anwendung

CDI, Persistenz, Konfiguration

@ApplicationScoped
public class KursService {
  @Inject KursRepository repo;
}

@Entity
public class Kurs { @Id @GeneratedValue public Long id; public String titel; }

@ApplicationScoped
public class KursRepository implements PanacheRepository<Kurs> { }
AspektActive RecordRepository
Query-Ortauf der Entityeigene Klasse
Kopplungenglose
Testbarkeitmäßiggut, mockbar
Passt füreinfache CRUDgrößere Domänen

Konfiguration typisiert, Eingaben validiert:

@ConfigMapping(prefix = "kurs")
interface KursConfig { int maxPlaetze(); }

public record NeuerKurs(@NotBlank String titel, @Min(1) int plaetze) { }

Modul: Kernkonzepte: DI, Persistenz, Konfiguration, Tests

Reaktiv oder Virtual Thread

@GET
public Uni<List<Kurs>> alle() { return repo.listAllAsync(); }

@GET @Path("/sync")
@RunOnVirtualThread
public List<Kurs> alleSync() { return repo.listAll(); }

Uni und Multi sind lazy — ohne Abonnent passiert nichts. Und ein blockierender Aufruf auf dem Event Loop quittiert sich mit „blocked event loop thread”.

Microservice-Bausteine

@RegisterRestClient(configKey = "katalog")
public interface KatalogClient {
  @GET @Path("/kurse")
  @Retry(maxRetries = 2)
  @Timeout(2000)
  List<Kurs> alle();
}

@Retry ohne @Timeout ist die klassische Falle: Hängende Aufrufe stauen sich, statt abgebrochen zu werden. Die Basis-URL gehört in die Konfiguration, nicht in den Code.

@Readiness
public class DbCheck implements HealthCheck {
  public HealthCheckResponse call() { return HealthCheckResponse.up("db"); }
}

@RolesAllowed("admin")
@DELETE @Path("/{id}")
public void loeschen(Long id) { }

Modul: Reaktives, Microservices & Deployment

Typische Fallen

  • Schreiben ohne @Transactional — keine Persistenz oder eine Exception.
  • drop-and-create in Produktion löscht Daten. Stattdessen Flyway.
  • Lazy Loading außerhalb der TransaktionLazyInitializationException.
  • @Valid vergessen — die Constraints greifen dann schlicht nicht.
  • Profil-Präfix falsch (%prod statt %production oder umgekehrt) — der Wert wird kommentarlos ignoriert.
  • Liveness und Readiness verwechselt → Pod-Neustarts oder Fehlrouting.
  • Reflection ohne Registrierung bricht im Native Image, nicht vorher.
  • Kein Docker/Podman aktiv → Dev Services und Testcontainers starten nicht.
  • Secrets in application.properties statt in Umgebungsvariablen.

Zum Seminar Quarkus-Training