Einleitung: Warum Go die ideale Sprache für Mikroservices ist?
\n\nDie Mikroservice-Architektur ist zum De-facto-Standard für die Entwicklung moderner, skalierbarer Anwendungen geworden. Die Sprache Go (Golang), die in den Tiefen von Google entwickelt wurde, eignet sich aufgrund ihrer Einfachheit, Leistungsfähigkeit und integrierten Unterstützung für Nebenläufigkeit ideal für diese Aufgabe. In diesem Artikel werden wir den gesamten Zyklus der Erstellung eines Mikroservices in Go durchgehen: vom Architekturentwurf bis zur Bereitstellung in der Produktion.
\n\nGo bietet schnelle Kompilierung, minimalen Speicherverbrauch und native Unterstützung für Goroutinen – leichtgewichtige Threads. Dies macht es zu einer ausgezeichneten Wahl für hochbelastete verteilte Systeme. Wir werden die wichtigsten Konzepte betrachten, Codebeispiele schreiben und Best Practices diskutieren.
\n\n1. Entwurf der Mikroservice-Architektur in Go
\n\n1.1. Prinzipien der Mikroservice-Architektur
\n\nBevor wir Code schreiben, müssen die Grenzen der Mikroservices definiert werden. Die grundlegenden Prinzipien:
\n\n- \n
- Einzelverantwortung (Single Responsibility) – jeder Service ist für eine Geschäftsfunktion verantwortlich. \n
- Unabhängige Bereitstellung – jeder Mikroservice kann aktualisiert werden, ohne das gesamte System anzuhalten. \n
- Lockere Kopplung (Loose Coupling) – Services kommunizieren über klar definierte APIs. \n
- Dezentralisierung der Datenverwaltung – jeder Service hat seine eigene Datenbank. \n
1.2. Projektstruktur für einen Mikroservice in Go
\n\nEmpfohlene Ordnerstruktur für einen Mikroservice in Go:
\n\nmy-service/\n├── cmd/\n│ └── server/\n│ └── main.go # Einstiegspunkt\n├── internal/\n│ ├── handler/ # HTTP/gRPC-Handler\n│ ├── service/ # Geschäftslogik\n│ ├── repository/ # Datenbankzugriff\n│ └── model/ # Datenstrukturen\n├── pkg/\n│ └── api/ # Gemeinsame Proto-Dateien (gRPC)\n├── config/\n│ └── config.go # Konfiguration\n├── migrations/ # Datenbankmigrationen\n├── Dockerfile\n└── go.mod\n\n1.3. Beispiel eines einfachen Mikroservices
\n\nErstellen wir einen einfachen HTTP-Mikroservice zur Benutzerverwaltung. Beginnen wir mit der Definition des Modells und des Repositories:
\n\n// internal/model/user.go\npackage model\n\ntype User struct {\n ID int64 `json:"id"`\n Name string `json:"name"`\n Email string `json:"email"`\n}\n\n// internal/repository/user_repo.go\npackage repository\n\nimport (\n "context"\n "my-service/internal/model"\n)\n\ntype UserRepository interface {\n GetByID(ctx context.Context, id int64) (*model.User, error)\n Create(ctx context.Context, user *model.User) (int64, error)\n}\n\ntype inMemoryRepo struct {\n users map[int64]*model.User\n nextID int64\n}\n\nfunc NewInMemoryRepo() UserRepository {\n return &inMemoryRepo{\n users: make(map[int64]*model.User),\n nextID: 1,\n }\n}\n\nfunc (r *inMemoryRepo) GetByID(ctx context.Context, id int64) (*model.User, error) {\n user, ok := r.users[id]\n if !ok {\n return nil, fmt.Errorf("user not found")\n }\n return user, nil\n}\n\nfunc (r *inMemoryRepo) Create(ctx context.Context, user *model.User) (int64, error) {\n user.ID = r.nextID\n r.users[user.ID] = user\n r.nextID++\n return user.ID, nil\n}\n\n2. Kommunikation zwischen Mikroservices: REST, gRPC und Warteschlangen
\n\n2.1. REST-API in Go
\n\nFür die synchrone Kommunikation werden am häufigsten REST oder gRPC verwendet. Betrachten wir einen REST-Controller mit der Standardbibliothek net/http und dem Router chi:
// internal/handler/user_handler.go\npackage handler\n\nimport (\n "encoding/json"\n "net/http"\n "strconv"\n "my-service/internal/service"\n "github.com/go-chi/chi/v5"\n)\n\ntype UserHandler struct {\n svc *service.UserService\n}\n\nfunc NewUserHandler(svc *service.UserService) *UserHandler {\n