Go on One VPS: Production Handbook

Wie Sie einen Go-Service schreiben, den Sie auf einem Server einfach laufen lassen können: Shutdown, Timeouts, Speicher und systemd, mit einem lauffähigen Referenzservice hinter jedem Listing.

Bei Polar kaufen: $39 Einmalkauf · v0.1.0 · Sofort-Download über Polar

Cover von Go on One VPS: Production Handbook
Ausgabe eines echten Testlaufs, kein Mock-up.

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
1Projektstruktur für einen kleinen Service
2Konfiguration aus der Umgebung: alles validieren, früh scheitern
3Strukturiertes Logging mit log/slog, ohne Secrets preiszugeben
4Timeouts des HTTP-Servers
5Graceful Shutdown
6Health versus Readiness
7Context, Abbruch und Checks auf Goroutine-Leaks
8Datenbankzugriff mit SQLite: WAL, ein Writer, Migrationen
9Fehler und Panics
10Metriken und pprof, abgesichert
11Testen
12Bauen: statische, reproduzierbare Binaries
13systemd: Unit, Härtung, Restart, Stop
14Speicher: was ein Go-Prozess unter Druck tut
15Deployment mit Release-Ordnern
16Hä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 habenWas passiert ist
SIGTERM mit einem 1.5 s langen Job in ArbeitNeue 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 ServiceEnde nach 2 ms
SIGTERM mit einem 9 s langen Job und 500 ms Shutdown-LimitEnde nach 515 ms mit Exit-Code 1, der Job wurde zurück in die Queue gestellt
Client, der Header langsam sendet, 300 ms Header-TimeoutVerbindung nach 295 ms getrennt
systemctl stop mit einer 3 s langen Anfrage in ArbeitAnfrage lieferte 200, der Stop dauerte 3.19 s
kill -9 unter systemd2.10 s später wieder gesund
Zwei Builds aus verschiedenen VerzeichnissenByte-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.

ModusAnfragen pro Sekunde (3 Läufe)
Schreiben9,190 bis 11,189 (p99 8.4 bis 11.7 ms)
Lesen13,541 bis 18,421
Health-Endpoint23,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

Herunterladen

Bei Polar kaufen: $39

Zahlung, Steuern und Rechnung übernimmt Polar als Merchant of Record. Den Download-Link erhalten Sie nach dem Checkout.