4 Go Gopher turnen über das inovex-Logo

Go Meetup Q&A: Eure Fragen beantwortet!

Autor:in
Lesezeit
7 ​​min

Bei unserem Meetup zur Programmiersprache Go blieben aus Zeitgründen einige Fragen unbeantwortet. Wir haben sie hier gesammelt und von unseren Expert:innen beantworten lassen.

Wo/wie haltet ihr den State für Terraform oder wie die Schnittpunkte zwischen Infrastruktur und den Microservices?

Den Terraform-State für alle Services haben wir in einen S3 Bucket gelegt. Den Bucket und die Dynamo Tables selbst haben wir in einem eigenen Terraform Repo angelegt. Die Schnittstellen zwischen den Services und Terraform beruhen hauptsächlich auf Naming Conventions und Umgebungsvariablen in der GitlabCI Pipeline

Was habt ihr als Authentifizierungsmechanismus verwendet?

Bevor das Projekt von einem kundeninternen Team übernommen wurde, haben wir verschiedene User nur anhand ihrer Device ID identifiziert – ein eigenes Nutzerkonto gab es in dem Sinne nicht, dementsprechend auch nicht die Anforderung, User zu authentifizieren.

Prinzipiell eignet sich wie bei klassischen Microservices sehr gut alles, was stateless ist (oauth 2, OIDC). Da bietet einerseits AWS verschiedene Möglichkeiten, andererseits kann man, wenn man will, eigene Lösungen deployen (etwa Keycloak) oder sogar etwas spezialisiertes entwickeln. Damit haben wir aber keine Erfahrung gemacht.

Habt ihr bereut, DynamoDB genommen zu haben?

Das ist wohl ein wenig zufriedenstellendes it depends. DynamoDB ist nicht das Allheilmittel – für einige UseCases wären wir wohl mit einer relationalen DB schneller am Ziel gewesen – für andere Anforderungen (gerade Lacher und Views) hat es super gepasst und skaliert super einfach mit. In Summe bereue ich es nicht, Datenmodelle entwickeln sich weiter und je nach Anforderung kann es in jeder DB zur Herausforderung werden.

Als Key/Value-Store mit extra-Features ist es eine schöne Lösung, wenn man noch nicht so genau weiß, wo die Reise hingeht und noch sehr viel hin- und herschiebt. Dadurch, dass es DBaaS ist, nimmt es einem auch sehr viel Setup- und Wartungsaufwand ab. Früher oder später sind wir dann in das eine oder andere Problem gelaufen, was uns zum Um-die-Ecke-Denken zwang, teilweise weil es nunmal ein anderes Paradigma ist und teilweise wegen Dynamo-spezifischer Eigenarten.

Für den Start eines MVPs ist das Gesamtbild eher positiv, darüber hinaus gibt es unserer Einschätzung nach sehr harte Grenzen, an die man je nach Projekt recht schnell stößt. Skalierungsprobleme hatten wir nicht.

Warum ist Go auf Lambda denn nun besonders geeignet für schnelle MVPs? Ist man nicht viel schneller, wenn man ein funktionierendes System mit vielen Built-ins gibt, bei denen man z.B. das Logging nicht selbst bauen muss, sondern es schon da ist?

Hier kommt es auf das Ziel an, und die Unterscheidung zwischen (Wegwerf-)Prototypen und einem MVP. Prototypen haben nicht den Anspruch, irgendwann ein Produkt zu werden, sondern beweisen erstmal die Machbarkeit oder liefern neue Erkenntnisse über noch unbekanntes Terrain. Ein Minimal Viable Product will und soll ein Produkt sein, das die Abstriche nicht in der Qualität sondern im Funktionsumfang macht.

Prototypen können in einem kleinen Team, das gut eingespielt ist, bestimmt schneller gebaut werden, tragen auch zur Entscheidungsfindung bei, werden dann aber üblicherweise nicht weiter verfolgt.

Go hat vom Funktionsumfang her eine der komplettesten Standard Libraries. Noch mehr würde man nur von Frameworks abgenommen bekommen, die wiederum andere Nachteile und Einschränkungen mit sich bringen.

Die Chance, dass ein MVP nach erfolgreicher Evaluierung einfach übergeben bzw., das Team skaliert werden kann steigt mit Go durch die Einfachheit und das Idiomatische – in unserem Falle konnten selbst nicht-Go-Entwickler:innen sich in kurzer Zeit zurechtfinden und produktiv mit entwickeln. Es ist also nur die erste Iteration einer richtigen Produktentwicklung.

Wenn JSON bei Go so schwierig ist, macht es das dann nicht zu einem schlechtem API Server? Oder gibt es bessere/andere Module für JSON bei Go?

So weit würde ich nicht gehen. Grundsätzlich gibt es auch andere Module als das der Standard Library. Die haben wir nicht ausprobiert, stattdessen haben wir stellenweise Workarounds eingebaut.

Eines der angesprochenen Probleme war, dass nicht erkennbar ist, ob für einen Wert 0 übergeben wurde oder ob der Wert gar nicht übergeben wurde. Da kann z.B. das Feld im Struct als Pointer definiert werden, der Standardwert dafür ist nil. Wenn aber tatsächlich 0 übergeben wird, steht im Struct ein Pointer auf 0, der beim Aufruf dann automatisch de-referenziert wird.

Dennoch könnte man so etwas komfortabel auch beim Parsen abfangen. Und das wäre eine Option, die wir an einigen Stellen im Projekt vermisst haben. Im Kontrast dazu sorgt DisallowUnknownFields()  dafür, dass JSON-Objekte, die zu viele Werte enthalten, beim Parsen einen Error erzeugen. Das war für uns aber nutzlos, weil es uns keinen Mehrwert gebracht hat, die API strikt zu machen.

Habt ihr schlechte Erfahrungen mit Cold Starts von Lambdas gemacht? Falls ja, wie seid ihr damit umgegangen?

Ursprünglich haben wir uns auch aus diesem Grund für Go entschieden, aber AWS scheint da viel zu verbessern und die einzelnen Laufzeitumgebungen geben sich nicht mehr viel. Die Startup-Zeit der Runtime selbst ist in Go sehr kurz im Vergleich zu z.B. Spring, was man in Java oder Kotlin verwenden würde. Daran wird natürlich von allen Ecken fleißig gearbeitet.

Auch damals (Ende 2019) gab es die Alternative, Micronaut und GraalVM zu verwenden, das wirkte aber einerseits wenig production ready und andererseits umständlich im Vergleich zu Go.

Bei Smyle haben wir in der Regel 24/7 Traffic, was Cold Starts nur direkt nach einem Deployment merkbar macht. Es wurde auch über Lambda Warming diskutiert, wir haben uns dann allerdings dagegen entschieden. Wenn die Latenzanforderungen so strikt sind, dass ein gelegentlicher Cold Start für vereinzelte User (trotz Optimierung) nicht verkraftet werden kann, sind Lambdas schlicht die falsche Wahl.

Können Metriken bereitgestellt werden bei Lambdas? Habt ihr auch Metriken erfasst über etwa Request Durations? Logs erscheinen an der Stelle umständlich!

Wenn aktiviert, ist das alles bereits in Cloudwatch vorhanden.

Logs haben wir dann für Metriken verwendet, die fachlicher oder feingranularer als die Pro-Lambda-Metriken waren. Das klingt nach mehr Aufwand als es wirklich war, nachdem wir wussten, dass ein ELK Stack für den Betrieb der Anwendung bereit gestellt wurde.

Welches API Gateway wurde genutzt? AWS API Gateway? Oder ein eigenes? (Kong, Apigee, etc?) Warum gerade dieses?

Wir waren komplett in der AWS Welt-unterwegs, haben also auf das AWS API Gateway gesetzt. Das war wohl keine 100% bewusste Entscheidung, sondern aufgrund des MVP-Charakters und des Quickstarts eine pragmatische und stabile Lösung die einfach funktioniert hat.

Wollt ihr beim nächsten Meetup live dabei sein? Dann schaut euch hier unsere Meetup-Gruppen an!

Hat dir der Beitrag gefallen?

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Ähnliche Artikel