Für wen es ist
Sie schreiben Go, und Ihr Service läuft auf einer einzelnen Linux-Maschine unter systemd. Vielleicht ist es eine API mit Hintergrund-Worker und SQLite, ein Webhook-Empfänger oder ein internes Tool, auf das sich die ganze Firma verlässt. Es läuft. Sie wollen wissen, was an den Rändern passiert: bei einem Deployment, während noch Anfragen laufen, bei einem Client, der seine Header nie zu Ende sendet, bei einem Container mit zu wenig Speicher, bei einem Absturz um 3 Uhr nachts.
Das ist kein Go-Tutorial. Es setzt voraus, dass Sie die Sprache kennen und schon etwas ausgeliefert haben. Für eine Einführung in Goroutinen sind die bekannten Go-Bücher der bessere Einstieg.
Das steckt drin
Ein Buch mit 16 Kapiteln, rund 2,000 Zeilen, und ein kleiner Referenzservice, aus dem jedes Go-Listing im Buch stammt. Ein Skript prüft, dass jeder der 60 Codeblöcke mit dem getesteten Quellcode übereinstimmt. Nichts im Text ist also ein Schnipsel, den niemand ausgeführt hat.
| # | Kapitel |
|---|---|
| 1 | Projektstruktur für einen kleinen Service |
| 2 | Konfiguration aus der Umgebung: alles validieren, früh scheitern |
| 3 | Strukturiertes Logging mit log/slog, ohne Secrets preiszugeben |
| 4 | Timeouts des HTTP-Servers |
| 5 | Graceful Shutdown |
| 6 | Health versus Readiness |
| 7 | Context, Abbruch und Checks auf Goroutine-Leaks |
| 8 | Datenbankzugriff mit SQLite: WAL, ein Writer, Migrationen |
| 9 | Fehler und Panics |
| 10 | Metriken und pprof, abgesichert |
| 11 | Testen |
| 12 | Bauen: statische, reproduzierbare Binaries |
| 13 | systemd: Unit, Härtung, Restart, Stop |
| 14 | Speicher: was ein Go-Prozess unter Druck tut |
| 15 | Deployment mit Release-Ordnern |
| 16 | Häufige Produktionsfehler, jeweils mit einem Check, der sie findet |
Dazu kommen der Referenzservice (Standardbibliothek plus ein SQLite-Treiber), ein Lastgenerator, ein kleines Speicherexperiment, die systemd-Unit und ein Dockerfile, drei Checklisten und ein Docker-Harness, das jeden Check aus einem sauberen Container neu ausführt. Die Ausgabe unseres letzten vollständigen Laufs liegt bei, damit Sie vergleichen können.
Was die Tests zeigen
Die Kapitel zu Shutdown und systemd stützen sich auf Tests, die das echte Binary starten und echte Signale senden.
| Was wir getan haben | Was passiert ist |
|---|---|
| SIGTERM mit einem 1.5 s langen Job in Arbeit | Neue Verbindungen wurden nach 11 ms abgelehnt, die laufende Anfrage endete nach 1.399 s, der Prozess beendete sich nach 1.669 s mit Exit-Code 0 |
| SIGTERM an einen untätigen Service | Ende nach 2 ms |
| SIGTERM mit einem 9 s langen Job und 500 ms Shutdown-Limit | Ende nach 515 ms mit Exit-Code 1, der Job wurde zurück in die Queue gestellt |
| Client, der Header langsam sendet, 300 ms Header-Timeout | Verbindung nach 295 ms getrennt |
systemctl stop mit einer 3 s langen Anfrage in Arbeit | Anfrage lieferte 200, der Stop dauerte 3.19 s |
kill -9 unter systemd | 2.10 s später wieder gesund |
| Zwei Builds aus verschiedenen Verzeichnissen | Byte-identische Binaries (und unterschiedliche, wenn man -trimpath weglässt, als Kontrolle) |
Die systemd-Unit bringt Härtungsoptionen mit. Das Ergebnis lesen wir aus dem laufenden Prozess zurück, statt der Datei zu vertrauen: keine Capabilities, ein seccomp-Filter, schreibgeschütztes /usr und /etc, ein Speicherlimit. systemd-analyze security bewertete die Unit mit einem Exposure-Wert von 1.4.
Durchsatz und Speicher
Aufbau: Docker Desktop auf einem Apple-Silicon-Laptop, 8 CPUs, Service, Lastgenerator und Datenbank in einem Container, 16 Clients, pro Modus drei Läufe à 8 Sekunden.
| Modus | Anfragen pro Sekunde (3 Läufe) |
|---|---|
| Schreiben | 9,190 bis 11,189 (p99 8.4 bis 11.7 ms) |
| Lesen | 13,541 bis 18,421 |
| Health-Endpoint | 23,032 bis 26,757 |
Der Resident Memory lag im Leerlauf bei 13 MiB und nach dem Lastlauf bei 23 MiB, die Spitze bei 25 MiB.
GOMEMLIMIT, gemessen
Kapitel 14 sagt Ihnen nicht einfach, Sie sollen GOMEMLIMIT setzen und weitermachen. Es lässt ein kleines Programm mit 40 MiB Live-Heap in einem Container laufen, der auf 80 MiB begrenzt ist. Ohne Limit wurde es in 3 von 3 Läufen vom OOM-Killer beendet. Mit GOMEMLIMIT=56MiB überlebte es 3 von 3, und zwar zum Preis von etwa viermal so vielen Garbage Collections. Das Buch erklärt auch, warum das Limit weich ist und was das für die Dimensionierung heißt.
Voraussetzungen und Format
Go 1.24 oder neuer. Docker nur, wenn Sie das Harness erneut laufen lassen wollen. Alles ist Markdown, Go-Quellcode, Shell und Konfigurationsdateien: kein PDF-Schutz, kein Account, überall lesbar.
Häufige Fragen
Ist das ein Buch für Einsteiger?
Nein. Es setzt voraus, dass Sie bereits Go schreiben. Es geht um die Produktionsseite: was der Prozess tut, wenn etwas schiefgeht.
Behandelt es auch Postgres?
Der Referenzservice und seine Tests nutzen SQLite. Das Datenbankkapitel enthält außerdem Hinweise für Postgres.
Worin unterscheidet es sich vom Go Webhook Receiver Starter?
Der Starter ist ein kleines Produkt, das Sie betreiben. Das Handbuch liefert die Überlegungen und Tests hinter einem gut erzogenen Go-Service, mit einem anderen Referenzservice.
Darf ich den Code in eigenen Projekten verwenden?
Ja, in Ihren eigenen Projekten und auf Ihren eigenen Servern oder denen Ihres Arbeitgebers. Das Buch und das Kit dürfen Sie nicht weiterverkaufen oder weitergeben.
Änderungsprotokoll
- 0.1.0: erstes Release.
Weiterlesen
- Graceful shutdown for a Go HTTP server under systemd (Englisch)
- GOMEMLIMIT in an 80 MB container, with the numbers (Englisch)
- Go SQLite reads returning 404 for rows that exist (Englisch)
- log/slog setup for a small Go service on journald (Englisch)
- Go HTTP server timeouts that survive slow and stuck clients (Englisch)
Herunterladen
Zahlung, Steuern und Rechnung übernimmt Polar als Merchant of Record. Den Download-Link erhalten Sie nach dem Checkout.