Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Microservices mit Java und Go im Vergleich

320 views

Published on

JavaLand 2019, Brühl: Vortrag von Johannes Weigend (@JohannesWeigend, Technischer Geschäftsführer bei QAware)

=== Dokument bitte herunterladen, falls unscharf! Please download slides if blurred! ===

Abstract:
Java nimmt nach dem TIOBE Index 2018 unangefochten Platz 1 bei den weltweit eingesetzten Programmiersprachen ein. Es ist ausgereift, stabil und verfügt über ein immenses Open-Source-Ökosystem. Was will man mehr? Obwohl Java gerade für die Backend-Entwicklung attraktiv ist, hat Google 2008 eine eigene Programmiersprache für Backend -Infrastrukturkomponenten entwickelt und Open Source gestellt: Golang oder kurz Go.

Interessant an Go ist, dass die Grundbausteine von Cloud-Plattformen wie OpenShift oder die Google Container Platform mit Go erstellt wurden. Docker, Kubernetes, Helm, Grafana oder Prometheus. Alles ist mit Go programmiert.

Die Fragen aus der Sicht von Java-Experten sind:

- Was macht Go für die Cloud so interessant?
- Gibt es Funktionen, die Java Programmierer kennen sollten, und wenn ja welche?

Der Vortrag beleuchtet die Stärken und Schwächen von Go gegenüber Java und gibt Hinweise, für welche Art von Projekten Go eine valide Alternative ist und wie ein Best-Of-Breed-Ansatz aussehen kann.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Microservices mit Java und Go im Vergleich

  1. 1. AboutAboutAboutAbout Software Architekt, Developer, CTOSoftware Architekt, Developer, CTOSoftware Architekt, Developer, CTOSoftware Architekt, Developer, CTO Java Certi ed TrainerJava Certi ed TrainerJava Certi ed TrainerJava Certi ed Trainer Java RockstarJava RockstarJava RockstarJava Rockstar 3333
  2. 2. AgendaAgendaAgendaAgenda Java und Go im ÜberblickJava und Go im ÜberblickJava und Go im ÜberblickJava und Go im Überblick Go Programmierung in a NutshellGo Programmierung in a NutshellGo Programmierung in a NutshellGo Programmierung in a Nutshell Microservice Entwicklung mit HTTP/JSON und plain GoMicroservice Entwicklung mit HTTP/JSON und plain GoMicroservice Entwicklung mit HTTP/JSON und plain GoMicroservice Entwicklung mit HTTP/JSON und plain Go Microservice Entwicklung mit Protocol Bu ers und Google GRPCMicroservice Entwicklung mit Protocol Bu ers und Google GRPCMicroservice Entwicklung mit Protocol Bu ers und Google GRPCMicroservice Entwicklung mit Protocol Bu ers und Google GRPC Cloud Native Microservices mit go-kitCloud Native Microservices mit go-kitCloud Native Microservices mit go-kitCloud Native Microservices mit go-kit Best of Breed -Best of Breed -Best of Breed -Best of Breed - Was verwendet man wann?Was verwendet man wann?Was verwendet man wann?Was verwendet man wann? 4444
  3. 3. 5555555
  4. 4. Go im ÜberblickGo im ÜberblickGo im ÜberblickGo im Überblick Go wurde als C/C++ Alternative zur Backendentwicklung bei Google entwickeltGo wurde als C/C++ Alternative zur Backendentwicklung bei Google entwickeltGo wurde als C/C++ Alternative zur Backendentwicklung bei Google entwickeltGo wurde als C/C++ Alternative zur Backendentwicklung bei Google entwickelt Go ist eine Open Source Programmiersprache für verteilte und parallele SystemeGo ist eine Open Source Programmiersprache für verteilte und parallele SystemeGo ist eine Open Source Programmiersprache für verteilte und parallele SystemeGo ist eine Open Source Programmiersprache für verteilte und parallele Systeme (systemnah)(systemnah)(systemnah)(systemnah) Das Go Kernteam ist prominent: Robert Griesheimer (Hotspot-VM), Ken ThompsonDas Go Kernteam ist prominent: Robert Griesheimer (Hotspot-VM), Ken ThompsonDas Go Kernteam ist prominent: Robert Griesheimer (Hotspot-VM), Ken ThompsonDas Go Kernteam ist prominent: Robert Griesheimer (Hotspot-VM), Ken Thompson (UX/B) und Rob Pike (UTF-8)(UX/B) und Rob Pike (UTF-8)(UX/B) und Rob Pike (UTF-8)(UX/B) und Rob Pike (UTF-8) Go wird seit 2008 aktiv entwickelt (Aktuelle Version 1.11)Go wird seit 2008 aktiv entwickelt (Aktuelle Version 1.11)Go wird seit 2008 aktiv entwickelt (Aktuelle Version 1.11)Go wird seit 2008 aktiv entwickelt (Aktuelle Version 1.11) Go istGo istGo istGo ist DIEDIEDIEDIEDIEDIEDIE Sprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.ioSprache hinter dem Cloud Native Stack. Siehe www.cncf.io Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd,Alle wesentlichen Komponenten sind in Go geschrieben: Docker, Kubernetes, Etcd, Prometheus, GrafanaPrometheus, GrafanaPrometheus, GrafanaPrometheus, Grafana 6666
  5. 5. Go im Überblick - DesignzieleGo im Überblick - DesignzieleGo im Überblick - DesignzieleGo im Überblick - Designziele KISS (Schlüsselwörter: Go=25,KISS (Schlüsselwörter: Go=25,KISS (Schlüsselwörter: Go=25,KISS (Schlüsselwörter: Go=25, Ansi-C=32, Java=50)Ansi-C=32, Java=50)Ansi-C=32, Java=50)Ansi-C=32, Java=50) Compiler: Schnell, Cross Compiler, BinärcodeCompiler: Schnell, Cross Compiler, BinärcodeCompiler: Schnell, Cross Compiler, BinärcodeCompiler: Schnell, Cross Compiler, Binärcode Realtime Garbage CollectorRealtime Garbage CollectorRealtime Garbage CollectorRealtime Garbage Collector Statisches Typsystem mit Laufzeitunterstützung (Keine Generics)Statisches Typsystem mit Laufzeitunterstützung (Keine Generics)Statisches Typsystem mit Laufzeitunterstützung (Keine Generics)Statisches Typsystem mit Laufzeitunterstützung (Keine Generics) Unterstützung von Nebenläu gkeit, Parallelität und Verteilung (Multi-Core / Cloud)Unterstützung von Nebenläu gkeit, Parallelität und Verteilung (Multi-Core / Cloud)Unterstützung von Nebenläu gkeit, Parallelität und Verteilung (Multi-Core / Cloud)Unterstützung von Nebenläu gkeit, Parallelität und Verteilung (Multi-Core / Cloud) Einfache Anbindung von C/C++ CodeEinfache Anbindung von C/C++ CodeEinfache Anbindung von C/C++ CodeEinfache Anbindung von C/C++ Code Statischer Linker (Single Binary)Statischer Linker (Single Binary)Statischer Linker (Single Binary) Ideal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerIdeal für Docker ContainerStatischer Linker (Single Binary) Ideal für Docker Container Sprachfeatures aus modernen, dynamischen SprachenSprachfeatures aus modernen, dynamischen SprachenSprachfeatures aus modernen, dynamischen SprachenSprachfeatures aus modernen, dynamischen Sprachen Unterstützt diverser Programmierstile (PP, OOP, FP)Unterstützt diverser Programmierstile (PP, OOP, FP)Unterstützt diverser Programmierstile (PP, OOP, FP)Unterstützt diverser Programmierstile (PP, OOP, FP) Kompatibel!Kompatibel!Kompatibel!Kompatibel! Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen!Go Programmierung soll Spaß machen! 7777
  6. 6. Schwächen von Java im Kontext von Microservices ? (1/2)Schwächen von Java im Kontext von Microservices ? (1/2)Schwächen von Java im Kontext von Microservices ? (1/2)Schwächen von Java im Kontext von Microservices ? (1/2) DisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,DisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,DisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,DisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,DisclaimerDisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Disclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Disclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,DisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,DisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,DisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,DisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimerDisclaimer Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM,Es gibt diverse neue Technologien in Java welche hier angreifen (z.B. GraalVM, Quarkus ...)Quarkus ...)Quarkus ...)Quarkus ...) RessourcenbedarfRessourcenbedarfRessourcenbedarfRessourcenbedarf Java Anwendungen haben einen hohen Grundbedarf an Ressourcen (RAM, CPU - StartupJava Anwendungen haben einen hohen Grundbedarf an Ressourcen (RAM, CPU - StartupJava Anwendungen haben einen hohen Grundbedarf an Ressourcen (RAM, CPU - StartupJava Anwendungen haben einen hohen Grundbedarf an Ressourcen (RAM, CPU - Startup Time (verursacht durch Class Loading)).Time (verursacht durch Class Loading)).Time (verursacht durch Class Loading)).Time (verursacht durch Class Loading)). DockerDockerDockerDocker Java Anwendungen benötigen zusätzlich eine JVM. Aufgrund der JVM AbhängigkeitenJava Anwendungen benötigen zusätzlich eine JVM. Aufgrund der JVM AbhängigkeitenJava Anwendungen benötigen zusätzlich eine JVM. Aufgrund der JVM AbhängigkeitenJava Anwendungen benötigen zusätzlich eine JVM. Aufgrund der JVM Abhängigkeiten enthalten viele Docker Container ein komplettes OS Filesystem Image.enthalten viele Docker Container ein komplettes OS Filesystem Image.enthalten viele Docker Container ein komplettes OS Filesystem Image.enthalten viele Docker Container ein komplettes OS Filesystem Image. FootprintFootprintFootprintFootprint Ein Hadoop Tool benötigt aufgrund der JARs schnell 100 MB. Aufgrund der dynamischenEin Hadoop Tool benötigt aufgrund der JARs schnell 100 MB. Aufgrund der dynamischenEin Hadoop Tool benötigt aufgrund der JARs schnell 100 MB. Aufgrund der dynamischenEin Hadoop Tool benötigt aufgrund der JARs schnell 100 MB. Aufgrund der dynamischen ClassLoader Architektur kann erst zur Laufzeit entschieden werden welche KlassenClassLoader Architektur kann erst zur Laufzeit entschieden werden welche KlassenClassLoader Architektur kann erst zur Laufzeit entschieden werden welche KlassenClassLoader Architektur kann erst zur Laufzeit entschieden werden welche Klassen benötigt werden. Oft ist das nur ein kleiner Teil des Codes.benötigt werden. Oft ist das nur ein kleiner Teil des Codes.benötigt werden. Oft ist das nur ein kleiner Teil des Codes.benötigt werden. Oft ist das nur ein kleiner Teil des Codes. 8888
  7. 7. Schwächen von Java im Kontext von Microservices ? (1/2)Schwächen von Java im Kontext von Microservices ? (1/2)Schwächen von Java im Kontext von Microservices ? (1/2)Schwächen von Java im Kontext von Microservices ? (1/2) ThreadsThreadsThreadsThreads Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen.Threads sind schwergewichtige Betriebssystem Ressourcen. Anwendungen können Threads blockieren.Anwendungen können Threads blockieren.Anwendungen können Threads blockieren.Anwendungen können Threads blockieren.Anwendungen können Threads blockieren.Anwendungen können Threads blockieren.Anwendungen können Threads blockieren.Anwendungen können Threads blockieren.Anwendungen können Threads blockieren.Anwendungen können Threads blockieren. Thread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führenThread Pools sind hier keine Lösung, da langlaufende Aktionen zur Blockade führen können, falls mehr Anfragen bearbeitet müssen als Threads im Pool zur Verfügung stehen.können, falls mehr Anfragen bearbeitet müssen als Threads im Pool zur Verfügung stehen.können, falls mehr Anfragen bearbeitet müssen als Threads im Pool zur Verfügung stehen.können, falls mehr Anfragen bearbeitet müssen als Threads im Pool zur Verfügung stehen. Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt.Go hat Go Routinen. Die Logik in Go Routinen wird abschnittsweise auf Threads verteilt. Damit kann man um Faktoren mehr Go Routinen als Threads starten.Damit kann man um Faktoren mehr Go Routinen als Threads starten.Damit kann man um Faktoren mehr Go Routinen als Threads starten.Damit kann man um Faktoren mehr Go Routinen als Threads starten. 9999
  8. 8. Daisy Chaining: 100.000 concurrent Go RoutinenDaisy Chaining: 100.000 concurrent Go RoutinenDaisy Chaining: 100.000 concurrent Go RoutinenDaisy Chaining: 100.000 concurrent Go Routinen Es macht Sinn sich Go also genauer anzusehen!Es macht Sinn sich Go also genauer anzusehen!Es macht Sinn sich Go also genauer anzusehen!Es macht Sinn sich Go also genauer anzusehen! packagepackagepackage main importimportimport "fmt" funcfuncfunc f(left, right chanchanchan intintint) { left <- 1 + <-right } funcfuncfunc main() { constconstconst n = 100000 leftmost := make(chanchanchan intintint) right := leftmost left := leftmost forforfor i := 0; i < n; i++ { right = make(chanchanchan intintint) gogogo f(left, right) left = right } gogogo funcfuncfunc(c chanchanchan intintint) { c <- 1 }(right) fmt.Println(<-leftmost) } 10101010
  9. 9. Go Programmierung in a NutshellGo Programmierung in a NutshellGo Programmierung in a NutshellGo Programmierung in a Nutshell 11111111
  10. 10. Hello World mit GoHello World mit GoHello World mit GoHello World mit Go Go Quelldateien sind UTF-8 kodiertGo Quelldateien sind UTF-8 kodiertGo Quelldateien sind UTF-8 kodiertGo Quelldateien sind UTF-8 kodiert Package Namen sind nicht hierarchisch!Package Namen sind nicht hierarchisch!Package Namen sind nicht hierarchisch!Package Namen sind nicht hierarchisch! Package Importe sind vollquali ziert, versioniert und hierarchisch!Package Importe sind vollquali ziert, versioniert und hierarchisch!Package Importe sind vollquali ziert, versioniert und hierarchisch!Package Importe sind vollquali ziert, versioniert und hierarchisch! Funktionen/Typen/Variablen die mit einem Großbuchstaben beginnen sind "public".Funktionen/Typen/Variablen die mit einem Großbuchstaben beginnen sind "public".Funktionen/Typen/Variablen die mit einem Großbuchstaben beginnen sind "public".Funktionen/Typen/Variablen die mit einem Großbuchstaben beginnen sind "public". Kleingeschriebene Bezeichner sind im Package sichtbar. Es gibt kein "private".Kleingeschriebene Bezeichner sind im Package sichtbar. Es gibt kein "private".Kleingeschriebene Bezeichner sind im Package sichtbar. Es gibt kein "private".Kleingeschriebene Bezeichner sind im Package sichtbar. Es gibt kein "private". packagepackagepackage main importimportimport "fmt" funcfuncfunc main() { fmt.Printf("Hello %s", "Programming with Go xE2x98xAFn") // xE2x98xAF -> fmt.Printf("Hello %s", "Programming with Go n") } 12121212
  11. 11. Funktionen und Kontrollstrukturen: Beispiel PalindromFunktionen und Kontrollstrukturen: Beispiel PalindromFunktionen und Kontrollstrukturen: Beispiel PalindromFunktionen und Kontrollstrukturen: Beispiel Palindrom // IsPalindrome implementation. Does only work for 1-Byte UTF-8 chars (ASCII). funcfuncfunc IsPalindrome(word stringstringstring) boolboolbool { forforfor pos := 0; pos < len(word)/2; pos++ { ififif word[pos] != word[len(word)-pos-1] { returnreturnreturn falsefalsefalse } } returnreturnreturn truetruetrue } Es gibt ausschließlich for Schleifen (kein while, do)Es gibt ausschließlich for Schleifen (kein while, do)Es gibt ausschließlich for Schleifen (kein while, do)Es gibt ausschließlich for Schleifen (kein while, do) Der Typ einer Variable steht hinter dem Namen!Der Typ einer Variable steht hinter dem Namen!Der Typ einer Variable steht hinter dem Namen!Der Typ einer Variable steht hinter dem Namen! Der Rückgabetyp einer Funktion steht hinter den Parametern!Der Rückgabetyp einer Funktion steht hinter den Parametern!Der Rückgabetyp einer Funktion steht hinter den Parametern!Der Rückgabetyp einer Funktion steht hinter den Parametern! Bedingungen werden nicht geklammertBedingungen werden nicht geklammertBedingungen werden nicht geklammertBedingungen werden nicht geklammert if, for ... Blöcke sind grundsätzlich geklammert {}if, for ... Blöcke sind grundsätzlich geklammert {}if, for ... Blöcke sind grundsätzlich geklammert {}if, for ... Blöcke sind grundsätzlich geklammert {} Strichpunkte werden i.R. weggelassenStrichpunkte werden i.R. weggelassenStrichpunkte werden i.R. weggelassenStrichpunkte werden i.R. weggelassen 13131313
  12. 12. Go kennt Pointer ähnlich zu C/C++Go kennt Pointer ähnlich zu C/C++Go kennt Pointer ähnlich zu C/C++Go kennt Pointer ähnlich zu C/C++ funcfuncfunc swap1(x, y intintint) { x, y = y, x } funcfuncfunc swap2(x *intintint, y *intintint) { *x, *y = *y, *x } funcfuncfunc swap3(x **intintint, y **intintint) { *x, *y = *y, *x } Die doppelt Zuweisung spart eine Variable (tmp) ein!Die doppelt Zuweisung spart eine Variable (tmp) ein!Die doppelt Zuweisung spart eine Variable (tmp) ein!Die doppelt Zuweisung spart eine Variable (tmp) ein! Pointer werden wie auch Werte per Kopie übergebenPointer werden wie auch Werte per Kopie übergebenPointer werden wie auch Werte per Kopie übergebenPointer werden wie auch Werte per Kopie übergeben Es gibt keine Pointer Arithmetik (p++) wie in C/C++Es gibt keine Pointer Arithmetik (p++) wie in C/C++Es gibt keine Pointer Arithmetik (p++) wie in C/C++Es gibt keine Pointer Arithmetik (p++) wie in C/C++ Pointer sind automatisch mit nil initialisiertPointer sind automatisch mit nil initialisiertPointer sind automatisch mit nil initialisiertPointer sind automatisch mit nil initialisiert 14141414
  13. 13. Go kennt Pointer ähnlich zu C/C++Go kennt Pointer ähnlich zu C/C++Go kennt Pointer ähnlich zu C/C++Go kennt Pointer ähnlich zu C/C++ funcfuncfunc main() { varvarvar a, b = 1, 2 fmt.Printf("a=%d, b=%dn", a, b) swap1(a, b) fmt.Printf("swap1(a,b) : a=%d, b=%dn", a, b) swap2(&a, &b) fmt.Printf("swap2(&a,&b) : a=%d, b=%dn", a, b) pa, pb := &a, &b swap3(&pa, &pb) fmt.Printf("swap3(&pa, &pb): a=%d, b=%dn", a, b) } 15151515
  14. 14. Warum Pointer?Warum Pointer?Warum Pointer?Warum Pointer? Anbindung von C-Code ohne Adapter (Java JNI)Anbindung von C-Code ohne Adapter (Java JNI)Anbindung von C-Code ohne Adapter (Java JNI)Anbindung von C-Code ohne Adapter (Java JNI) Unterscheidung zwischen Pointer und ValueUnterscheidung zwischen Pointer und ValueUnterscheidung zwischen Pointer und ValueUnterscheidung zwischen Pointer und Value Kontrolle über das Speicherlayout von Strukturen (siehe Project Valhalla bei Java)Kontrolle über das Speicherlayout von Strukturen (siehe Project Valhalla bei Java)Kontrolle über das Speicherlayout von Strukturen (siehe Project Valhalla bei Java)Kontrolle über das Speicherlayout von Strukturen (siehe Project Valhalla bei Java) Value Types ( ache Strukturen / analog zu C/C++)Value Types ( ache Strukturen / analog zu C/C++)Value Types ( ache Strukturen / analog zu C/C++)Value Types ( ache Strukturen / analog zu C/C++) typetypetype Point structstructstruct { x, y, z intintint} typetypetype Triangle structstructstruct { a, b, c Point // flach -> Project Valhalla! a, b, c *Point // wie in Java: 3 Pointer } typetypetype TSlice [] Triangle Immutability (Methoden können Objekte nicht ändern)Immutability (Methoden können Objekte nicht ändern)Immutability (Methoden können Objekte nicht ändern)Immutability (Methoden können Objekte nicht ändern) funcfuncfunc (Triangle t) Translate(Point p) Triangle { returnreturnreturn Triangle{t.a.move(p.x), t.b.move(p.y), t.c.move(p.z)} } 16161616161616161616
  15. 15. Go kennt keine Klassen sondern Typen und FunktionenGo kennt keine Klassen sondern Typen und FunktionenGo kennt keine Klassen sondern Typen und FunktionenGo kennt keine Klassen sondern Typen und Funktionen // Rational represents a rational number numerator/denominator. typetypetype Rational structstructstruct { numerator intintint denominator intintint } // Multiply method for rational numbers (x1/x2 * y1/y2) funcfuncfunc (x Rational) Multiply(y Rational) Rational { returnreturnreturn NewRational(x.numerator*y.numerator, x.denominator*y.denominator) } 17171717171717171717
  16. 16. Go hat Unit Testing bereits eingebautGo hat Unit Testing bereits eingebautGo hat Unit Testing bereits eingebautGo hat Unit Testing bereits eingebaut funcfuncfunc TestRational(t *testing.T) { r1 := NewRational(1, 2) r2 := NewRational(2, 4) // test equal ififif r1 != r2 { t.Error("1/2 should be equal to 2/4 but is not.") } // test multiply r3 := r1.Multiply(r2) ififif r3 != NewRational(1, 4) { t.Error(fmt.Sprintf("1/2 * 1/2 should be 1/4 but ist %v", r3)) } // test add r4 := r3.Add(r3) ififif r4 != NewRational(1, 2) { t.Error(fmt.Sprintf("1/4 + 1/4 should be 1/2 but ist %v", r4)) } } 18181818181818181818
  17. 17. Go kennt Polymorphismus nur über InterfacesGo kennt Polymorphismus nur über InterfacesGo kennt Polymorphismus nur über InterfacesGo kennt Polymorphismus nur über Interfaces // Sender is a interface to send mails. typetypetype Sender interfaceinterfaceinterface { // Send an email with a message. SendMail(message stringstringstring) } 19191919191919191919
  18. 18. Interfaces implementiert man durch Bereitstellung der gefordertenInterfaces implementiert man durch Bereitstellung der gefordertenInterfaces implementiert man durch Bereitstellung der gefordertenInterfaces implementiert man durch Bereitstellung der geforderten MethodenMethodenMethodenMethoden // MailSenderImpl is a sender object. typetypetype MailSenderImpl structstructstruct { address mail.Address } // NewMailSender constructs a mail sender with a delivery address. funcfuncfunc NewMailSender(address mail.Address) *MailSenderImpl { sender := new(MailSenderImpl) sender.address = address returnreturnreturn sender } // SendMail sends a mail to a receiver. funcfuncfunc (m *MailSenderImpl) SendMail(message stringstringstring) { log.Printf("Sending message with SMTP to %v. Message %s.", m.address, message) returnreturnreturn } 20202020202020202020
  19. 19. Das Go Interface ist wie bei Java polymorphDas Go Interface ist wie bei Java polymorphDas Go Interface ist wie bei Java polymorphDas Go Interface ist wie bei Java polymorph // Package client contains sample code for the mail components. packagepackagepackage client importimportimport "github.com/qaware/programmieren-mit-go/01_object-oriented-programming/mail/wire" // SendMail sends a mail to a receiver. funcfuncfunc SendMail(message stringstringstring) { // Create an implementation for the mail.Sender interface. varvarvar sender = wire.InitializeSender() sender.SendMail(message) } wire ist das Dependency Injection Framework des Go Cloud Development Kitwire ist das Dependency Injection Framework des Go Cloud Development Kitwire ist das Dependency Injection Framework des Go Cloud Development Kitwire ist das Dependency Injection Framework des Go Cloud Development Kit github.com/google/go-cloudgithub.com/google/go-cloudgithub.com/google/go-cloudgithub.com/google/go-cloudgithub.com/google/go-cloudgithub.com/google/go-cloudgithub.com/google/go-cloud(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud)(https://github.com/google/go-cloud) 21212121
  20. 20. OOP mit GoOOP mit GoOOP mit GoOOP mit Go Mehrere Interfaces können zu einem Interface kombiniert werdenMehrere Interfaces können zu einem Interface kombiniert werdenMehrere Interfaces können zu einem Interface kombiniert werdenMehrere Interfaces können zu einem Interface kombiniert werden Go unterstützt keine Vererbung sondern Typ Embedding (Delegation ohneGo unterstützt keine Vererbung sondern Typ Embedding (Delegation ohneGo unterstützt keine Vererbung sondern Typ Embedding (Delegation ohneGo unterstützt keine Vererbung sondern Typ Embedding (Delegation ohne syntaktischem Ballast)syntaktischem Ballast)syntaktischem Ballast)syntaktischem Ballast) Go unterstützt Polymorphismus nur über Interfaces nicht über EmbeddingGo unterstützt Polymorphismus nur über Interfaces nicht über EmbeddingGo unterstützt Polymorphismus nur über Interfaces nicht über EmbeddingGo unterstützt Polymorphismus nur über Interfaces nicht über Embedding Die Interface Hierarchie ist von der Typ Hierarchie komplett unabhängigDie Interface Hierarchie ist von der Typ Hierarchie komplett unabhängigDie Interface Hierarchie ist von der Typ Hierarchie komplett unabhängigDie Interface Hierarchie ist von der Typ Hierarchie komplett unabhängig 22222222
  21. 21. Go WerkzeugkastenGo WerkzeugkastenGo WerkzeugkastenGo Werkzeugkasten Compile, Build, Run von Anwendungen aus vielen Packages / QuelldateienCompile, Build, Run von Anwendungen aus vielen Packages / QuelldateienCompile, Build, Run von Anwendungen aus vielen Packages / QuelldateienCompile, Build, Run von Anwendungen aus vielen Packages / Quelldateien Unit Testing mit Test CoverageUnit Testing mit Test CoverageUnit Testing mit Test CoverageUnit Testing mit Test Coverage Pro ling mit pprof (CPU und Memory) -> FlamegraphsPro ling mit pprof (CPU und Memory) -> FlamegraphsPro ling mit pprof (CPU und Memory) -> FlamegraphsPro ling mit pprof (CPU und Memory) -> Flamegraphs Formatierung von Quelldateien mit go fmtFormatierung von Quelldateien mit go fmtFormatierung von Quelldateien mit go fmtFormatierung von Quelldateien mit go fmt Quellcode Style Checker mit go vetQuellcode Style Checker mit go vetQuellcode Style Checker mit go vetQuellcode Style Checker mit go vet Slideshows mit ausführbarem Go Code im BrowserSlideshows mit ausführbarem Go Code im BrowserSlideshows mit ausführbarem Go Code im BrowserSlideshows mit ausführbarem Go Code im Browser ............ Flame Graph runtim.. ru..strings.. r.. runtime.mallocgc (489 .. all r.. ru.. github.com/uber/go­torch/graph..pathAsString (7.49s) (3,276 samples, 98.67%) strings.Replace (1,784 samples, 53.73%) runtime.concatstrings..b.. runtime.rawstring (648 samples, .. runtim.. runtime.rawstrin.. runtim.. bytes.. runtime.makeslice (489.. r.. r..runtime.slicebytetostring (805 samples, 24.. r.. ru.. runtime.m.. github.com/uber/go­torch/graph..dfs (7.73s) (3,288 samples, 99.04%) r.. run.. runtime.mal.. runtim.. r.. st.. r.. runtim.. st.. r.. runtime.newarray (489 .. runtime.m.. r.. runtime.concatstring2.. runtime.rawst..r.. run.. runtim.. strings.. r.. runt.. strings.. runtime.mallocgc (489 .. runti.. runtime.. runtim.. runtime.slicebytet.. r.. runtim.. st.. r.. github.com/uber/go­torch/graph.getFormattedFunctionLabel (2,012 samples, 60.60%) r..run.. ru.. 23232323232323
  22. 22. Microservices mit GoMicroservices mit GoMicroservices mit GoMicroservices mit Go 24242424
  23. 23. RESTful Services mit JSON/XML - Das net/http PackageRESTful Services mit JSON/XML - Das net/http PackageRESTful Services mit JSON/XML - Das net/http PackageRESTful Services mit JSON/XML - Das net/http Package packagepackagepackage main importimportimport ( "log" "net/http" ) funcfuncfunc main() { router := http.NewServeMux() router.HandleFunc("/customers", getAllCustomers) log.Println("CustomerServer: Listening on http://localhost:8080/customers ...") log.Fatal(http.ListenAndServe(":8080", router)) } Als Router wird der Go HTTP Mulitplexer verwendet (mux)Als Router wird der Go HTTP Mulitplexer verwendet (mux)Als Router wird der Go HTTP Mulitplexer verwendet (mux)Als Router wird der Go HTTP Mulitplexer verwendet (mux) Der Router/Multiplexer leitet URL Aufrufe an eine Handlerfunktion weiterDer Router/Multiplexer leitet URL Aufrufe an eine Handlerfunktion weiterDer Router/Multiplexer leitet URL Aufrufe an eine Handlerfunktion weiterDer Router/Multiplexer leitet URL Aufrufe an eine Handlerfunktion weiter Das Gorilla Webframework ist eine gängige AlternativeDas Gorilla Webframework ist eine gängige AlternativeDas Gorilla Webframework ist eine gängige AlternativeDas Gorilla Webframework ist eine gängige Alternative 25252525
  24. 24. HandlerHandlerHandlerHandler // Customer type typetypetype Customer structstructstruct { Name stringstringstring `json:"name"` Address stringstringstring `json:"adress"` Tel stringstringstring `json:"tel"` } // Static customer data. varvarvar customers = []Customer{ Customer{"QAware GmbH", "Munich", "+49 000 12345678"}, Customer{"QAware GmbH", "Mainz", "+49 111 87654321"}, } // Handler to get all customers encoded as JSON funcfuncfunc getAllCustomers(w http.ResponseWriter, r *http.Request) { ififif err := json.NewEncoder(w).Encode(customers); err != nilnilnil { panic(err) } } Das JSON oder XML Marshalling wird über Kommentare gesteuertDas JSON oder XML Marshalling wird über Kommentare gesteuertDas JSON oder XML Marshalling wird über Kommentare gesteuertDas JSON oder XML Marshalling wird über Kommentare gesteuert Kommentare sind der Ersatz für Annotationen bei JavaKommentare sind der Ersatz für Annotationen bei JavaKommentare sind der Ersatz für Annotationen bei JavaKommentare sind der Ersatz für Annotationen bei Java 26262626
  25. 25. Go und Docker - Das Builder PatternGo und Docker - Das Builder PatternGo und Docker - Das Builder PatternGo und Docker - Das Builder Pattern # Build FROM golang:alpine as builder RUN mkdir /build ADD . /build/ WORKDIR /build RUN CGO_ENABLED=0 GOOS=linux gogogo build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o main . # Repackage FROM scratch COPY --from=builder /build/main /app/ WORKDIR /app CMD ["./main"] Der Container "builder" enthält die komplette Go Compiler Suite + ToolsDer Container "builder" enthält die komplette Go Compiler Suite + ToolsDer Container "builder" enthält die komplette Go Compiler Suite + ToolsDer Container "builder" enthält die komplette Go Compiler Suite + Tools Der generierte Container enthält ausschließlich das von Go generierte ProgrammDer generierte Container enthält ausschließlich das von Go generierte ProgrammDer generierte Container enthält ausschließlich das von Go generierte ProgrammDer generierte Container enthält ausschließlich das von Go generierte Programm Das Programm ist statisch gelinkt und hat keine weiteren AbhängigkeitenDas Programm ist statisch gelinkt und hat keine weiteren AbhängigkeitenDas Programm ist statisch gelinkt und hat keine weiteren AbhängigkeitenDas Programm ist statisch gelinkt und hat keine weiteren Abhängigkeiten Der nale Container ist damit wenige MB groß!!!Der nale Container ist damit wenige MB groß!!!Der nale Container ist damit wenige MB groß!!!Der nale Container ist damit wenige MB groß!!! 27272727
  26. 26. DEMODEMODEMODEMO # Makefile docker: docker build -t customer-service . docker images | grep customer-service dockerrun: docker run -p8080:8080 customer-service /app/main $ make docker ... Successfully tagged customer-service:latest docker images | grep customer-service customer-service latest 5e7e9794779a Less than a second ago 7,03MB 28282828282828282828282828
  27. 27. Die Go Bordmittel reichen nicht immer aus ...Die Go Bordmittel reichen nicht immer aus ...Die Go Bordmittel reichen nicht immer aus ...Die Go Bordmittel reichen nicht immer aus ... Alternative 1: Generierter Weblayer mit go-swagger (https://goswagger.io/)Alternative 1: Generierter Weblayer mit go-swagger (https://goswagger.io/)Alternative 1: Generierter Weblayer mit go-swagger (https://goswagger.io/)Alternative 1: Generierter Weblayer mit go-swagger (https://goswagger.io/) Alternative 2: RPC GeneratorenAlternative 2: RPC GeneratorenAlternative 2: RPC GeneratorenAlternative 2: RPC Generatoren Alternative 3: Microservice Frameworks: micro, go-kit ...Alternative 3: Microservice Frameworks: micro, go-kit ...Alternative 3: Microservice Frameworks: micro, go-kit ...Alternative 3: Microservice Frameworks: micro, go-kit ... 29292929
  28. 28. Microservices mit mit Go und gRPCMicroservices mit mit Go und gRPCMicroservices mit mit Go und gRPCMicroservices mit mit Go und gRPC gRPC ist ein binärer und e zienter RPC auf Basis von Protocolbu ersgRPC ist ein binärer und e zienter RPC auf Basis von Protocolbu ersgRPC ist ein binärer und e zienter RPC auf Basis von Protocolbu ersgRPC ist ein binärer und e zienter RPC auf Basis von Protocolbu ers gRPC hat Bindings zu allen gängigen Programmiersprachen (auch JS!)gRPC hat Bindings zu allen gängigen Programmiersprachen (auch JS!)gRPC hat Bindings zu allen gängigen Programmiersprachen (auch JS!)gRPC hat Bindings zu allen gängigen Programmiersprachen (auch JS!) gRPC unterstützt synchronen RPC, Streaming (client/server), Timeouts, Canceling, HTTP 2gRPC unterstützt synchronen RPC, Streaming (client/server), Timeouts, Canceling, HTTP 2gRPC unterstützt synchronen RPC, Streaming (client/server), Timeouts, Canceling, HTTP 2gRPC unterstützt synchronen RPC, Streaming (client/server), Timeouts, Canceling, HTTP 2 gRPC ist ideal für die Service zu Service KommunikationgRPC ist ideal für die Service zu Service KommunikationgRPC ist ideal für die Service zu Service KommunikationgRPC ist ideal für die Service zu Service Kommunikation 30303030
  29. 29. Beispiel Nummernserver mit gRPCBeispiel Nummernserver mit gRPCBeispiel Nummernserver mit gRPCBeispiel Nummernserver mit gRPC Go Schnittstellende nitionGo Schnittstellende nitionGo Schnittstellende nitionGo Schnittstellende nition // Package idserv contains the IDService API. packagepackagepackage idserv // IDService can be used to produce network wide unique ids. typetypetype IDService interfaceinterfaceinterface { // NewUUID generates an UUID with a given client prefix. NewUUID(clientID stringstringstring) stringstringstring } 31313131313131313131
  30. 30. Go Client und ImplementierungGo Client und ImplementierungGo Client und ImplementierungGo Client und Implementierung // GenerateIds calls n-times NewUUID() in a loop and returns the result as slice. funcfuncfunc GenerateIds(count intintint, service idserv.IDService) []stringstringstring { result := make([]stringstringstring, count) forforfor i := 0; i < count; i++ { result[i] = service.NewUUID("c1") } returnreturnreturn result } typetypetype IDServiceImpl structstructstruct { } varvarvar lastID int64int64int64 // The last given Id. // NewIDServiceImpl creates a new instance funcfuncfunc NewIDServiceImpl() *IDServiceImpl { returnreturnreturn new(IDServiceImpl) } // NewUUID implements the IDService interface. funcfuncfunc (ids *IDServiceImpl) NewUUID(clientID stringstringstring) stringstringstring { result := atomic.AddInt64(&lastID, 1) returnreturnreturn fmt.Sprintf("%v:%v", clientID, result) } 32323232323232323232
  31. 31. Die gRPC Protokollbuffer Definition idserv.protoDie gRPC Protokollbuffer Definition idserv.protoDie gRPC Protokollbuffer Definition idserv.protoDie gRPC Protokollbuffer Definition idserv.proto // The gRPC protobuf service definition service IDService { // NewUUID generates a globally unique ID rpc NewUUID (IdRequest) returns (IdReply) {} } // The client sends a unique id. message IdRequest { stringstringstring clientId = 1; } // The response message contains the uuid. message IdReply { stringstringstring uuid = 1; } gogogo get -u google.golang.org/grpc --> install GRPC gogogo get -u github.com/golang/protobuf/protoc-gen-gogogo --> install Protoc Go Plugin protoc -I remote/idserv/ remote/idserv/idserv.proto --go_out=plugins=grpc:remote/idserv 33333333333333333333333333
  32. 32. Der Protokollcompiler generiert idserv.pb.goDer Protokollcompiler generiert idserv.pb.goDer Protokollcompiler generiert idserv.pb.goDer Protokollcompiler generiert idserv.pb.go // IDServiceServer is the server API for IDService service. typetypetype IDServiceServer interfaceinterfaceinterface { // NewUUID generates a globally unique ID NewUUID(context.Context, *IdRequest) (*IdReply, error) } Schnittstellen zur Implementierung am ServerSchnittstellen zur Implementierung am ServerSchnittstellen zur Implementierung am ServerSchnittstellen zur Implementierung am Server Generierte Client Stubs für den AufrufGenerierte Client Stubs für den AufrufGenerierte Client Stubs für den AufrufGenerierte Client Stubs für den Aufruf Generierter Marshaling CodeGenerierter Marshaling CodeGenerierter Marshaling CodeGenerierter Marshaling Code 34343434
  33. 33. Server main()Server main()Server main()Server main() constconstconst ( port = ":50051" ) funcfuncfunc main() { lis, err := net.Listen("tcp", port) ififif err != nilnilnil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() idserv.RegisterIDServiceServer(s, &stub.Stub{}) // Register reflection service on gRPC server. reflection.Register(s) ififif err := s.Serve(lis); err != nilnilnil { log.Fatalf("failed to serve: %v", err) } } Die Server main() Funktion ist nicht generiert!Die Server main() Funktion ist nicht generiert!Die Server main() Funktion ist nicht generiert!Die Server main() Funktion ist nicht generiert! 35353535
  34. 34. ClientClientClientClient funcfuncfunc main() { conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) ififif err != nilnilnil { panic(fmt.Sprintf("did not connect: %v", err)) } c := idserv.NewIDServiceClient(conn) ctx, cancel := context.WithTimeout(context.Background(), time.Second) deferdeferdefer cancel() r, err := c.NewUUID(ctx, &idserv.IdRequest{ClientId: "client"}) ififif err != nilnilnil { log.Printf("could not generate id: %v", err) r.Uuid = "" } uuid := r.Uuid log.Println(uuid) } 36363636363636363636
  35. 35. "Modulith" On Demand - Das Proxy Pattern mit gRPC"Modulith" On Demand - Das Proxy Pattern mit gRPC"Modulith" On Demand - Das Proxy Pattern mit gRPC"Modulith" On Demand - Das Proxy Pattern mit gRPC 37373737373737
  36. 36. Der Proxy implementiert das API interfaceDer Proxy implementiert das API interfaceDer Proxy implementiert das API interfaceDer Proxy implementiert das API interface // NewUUID implements the IDService interface. funcfuncfunc (p *Proxy) NewUUID(clientID stringstringstring) stringstringstring { c := idserv.NewIDServiceClient(p.connection) ctx, cancel := context.WithTimeout(context.Background(), time.Second) deferdeferdefer cancel() r, err := c.NewUUID(ctx, &idserv.IdRequest{ClientId: clientID}) ififif err != nilnilnil { log.Printf("could not generate id: %v", err) r.Uuid = "" } Die generierte Go Funktion unterscheidet sich von einem lokalem FunktionsaufrufDie generierte Go Funktion unterscheidet sich von einem lokalem FunktionsaufrufDie generierte Go Funktion unterscheidet sich von einem lokalem FunktionsaufrufDie generierte Go Funktion unterscheidet sich von einem lokalem Funktionsaufruf Parameter, Returnwerte und Fehlerbehandlung sind unterschiedlichParameter, Returnwerte und Fehlerbehandlung sind unterschiedlichParameter, Returnwerte und Fehlerbehandlung sind unterschiedlichParameter, Returnwerte und Fehlerbehandlung sind unterschiedlich Der Proxy übernimmt das MappingDer Proxy übernimmt das MappingDer Proxy übernimmt das MappingDer Proxy übernimmt das Mapping Der Proxy dient als Fehlerfassade, Cirquitbreaker, Monitoring Fassade, Cache ...Der Proxy dient als Fehlerfassade, Cirquitbreaker, Monitoring Fassade, Cache ...Der Proxy dient als Fehlerfassade, Cirquitbreaker, Monitoring Fassade, Cache ...Der Proxy dient als Fehlerfassade, Cirquitbreaker, Monitoring Fassade, Cache ... 38383838
  37. 37. Der Stub delegiert an das API interfaceDer Stub delegiert an das API interfaceDer Stub delegiert an das API interfaceDer Stub delegiert an das API interface // Stub implements the idserv.IdServer GRPC server side typetypetype Stub structstructstruct{} // NewUUID implements idserv.IdService interface funcfuncfunc (s *Stub) NewUUID(c context.Context, r *idserv.IdRequest) (*idserv.IdReply, error) { deferdeferdefer funcfuncfunc() { ififif err := recover(); err != nilnilnil { log.Printf("Recovered from panic %v", err) } }() service := core.NewIDServiceImpl() returnreturnreturn &idserv.IdReply{Uuid: service.NewUUID(r.GetClientId())}, nilnilnil } Aufruf der BusinesslogikAufruf der BusinesslogikAufruf der BusinesslogikAufruf der Businesslogik Fehlerbehandlung auf KommunikationsebeneFehlerbehandlung auf KommunikationsebeneFehlerbehandlung auf KommunikationsebeneFehlerbehandlung auf Kommunikationsebene AusnahmebehandlungAusnahmebehandlungAusnahmebehandlungAusnahmebehandlung Technisches Setup (Logging, ...)Technisches Setup (Logging, ...)Technisches Setup (Logging, ...)Technisches Setup (Logging, ...) 39393939
  38. 38. 40404040
  39. 39. Was fehlt?Was fehlt?Was fehlt?Was fehlt? Service LocatorService LocatorService LocatorService Locator MetrikenMetrikenMetrikenMetriken TracingTracingTracingTracing MessagingMessagingMessagingMessaging Cirquit BreakerCirquit BreakerCirquit BreakerCirquit Breaker LoggingLoggingLoggingLogging ............ 41414141
  40. 40. Cloud Native Microservices mit Go-KitCloud Native Microservices mit Go-KitCloud Native Microservices mit Go-KitCloud Native Microservices mit Go-Kit github.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kit(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit)github.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kit(https://github.com/go-kit)github.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kit(https://github.com/go-kit)github.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kit(https://github.com/go-kit)github.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kitgithub.com/go-kit(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit)(https://github.com/go-kit) 42424242
  41. 41. Go-Kit definiert vier grundlegende AbstraktionenGo-Kit definiert vier grundlegende AbstraktionenGo-Kit definiert vier grundlegende AbstraktionenGo-Kit definiert vier grundlegende Abstraktionen TransportTransportTransportTransport EndpointEndpointEndpointEndpoint ServiceServiceServiceService Middleware (Decorator) zwischen Endpoint und ServiceMiddleware (Decorator) zwischen Endpoint und ServiceMiddleware (Decorator) zwischen Endpoint und ServiceMiddleware (Decorator) zwischen Endpoint und Service 43434343
  42. 42. Getting Started mit Go-KitGetting Started mit Go-KitGetting Started mit Go-KitGetting Started mit Go-Kit gogogo get github.com/kujtimiihoxha/kit # gogogo-kit CLI Neue Services anlegenNeue Services anlegenNeue Services anlegenNeue Services anlegen kit n s users kit n s bugs kit n s notification Service Schnittstellen de nierenService Schnittstellen de nierenService Schnittstellen de nierenService Schnittstellen de nieren // UsersService describes the service. typetypetype UsersService interfaceinterfaceinterface { // Add your methods here GetUserByMail(ctx context.Context, mailAddress stringstringstring) (user User, err error) } // User struct typetypetype User structstructstruct { Name stringstringstring Email stringstringstring ID stringstringstring } 44444444444444444444
  43. 43. Getting Started mit go-kit (2)Getting Started mit go-kit (2)Getting Started mit go-kit (2)Getting Started mit go-kit (2) // HTTP Handler generieren kit g s users // gRPC Handler generieren kit g s notification -t grpc // Run Service gogogo run users/cmd/mail.gogogo - Der Generator ist nicht Teil des gogogo-kit Frameworks - Der Generator liefert einen guten Anfang - Der Generator muss weiter verbessert werden (OpenSource!) // Test curl -d '{"Email":"j@w"}' -H "Content-Type: application/json" -X POST http://localhost:8081/get-user-by- 45454545454545454545
  44. 44. Microservices mit Go - ZusammenfassungMicroservices mit Go - ZusammenfassungMicroservices mit Go - ZusammenfassungMicroservices mit Go - Zusammenfassung Die Go Standardbibliothek unterstützt Low Level NetzwerkprogrammierungDie Go Standardbibliothek unterstützt Low Level NetzwerkprogrammierungDie Go Standardbibliothek unterstützt Low Level NetzwerkprogrammierungDie Go Standardbibliothek unterstützt Low Level Netzwerkprogrammierung Mit Go lassen sich einfach RESTful Webservices bauenMit Go lassen sich einfach RESTful Webservices bauenMit Go lassen sich einfach RESTful Webservices bauenMit Go lassen sich einfach RESTful Webservices bauen Mit Go lassen sich einfach GRPC Webservices bauen und anbindenMit Go lassen sich einfach GRPC Webservices bauen und anbindenMit Go lassen sich einfach GRPC Webservices bauen und anbindenMit Go lassen sich einfach GRPC Webservices bauen und anbinden Channels und Go Routinen vereinfachen parallele ServerprogrammierungChannels und Go Routinen vereinfachen parallele ServerprogrammierungChannels und Go Routinen vereinfachen parallele ServerprogrammierungChannels und Go Routinen vereinfachen parallele Serverprogrammierung Es gibt diverse Microservice Frameworks aber keine Standards wie z.B. JavaEEEs gibt diverse Microservice Frameworks aber keine Standards wie z.B. JavaEEEs gibt diverse Microservice Frameworks aber keine Standards wie z.B. JavaEEEs gibt diverse Microservice Frameworks aber keine Standards wie z.B. JavaEE Der Reifegrad der Frameworks und Bibliotheken ist SEHR unterschiedlichDer Reifegrad der Frameworks und Bibliotheken ist SEHR unterschiedlichDer Reifegrad der Frameworks und Bibliotheken ist SEHR unterschiedlichDer Reifegrad der Frameworks und Bibliotheken ist SEHR unterschiedlich 46464646
  45. 45. Für welche Anwendungen eignet sich Go?Für welche Anwendungen eignet sich Go?Für welche Anwendungen eignet sich Go?Für welche Anwendungen eignet sich Go? Hilfsprozesse wie Sidecar Container auf Cloud Plattformen (Kubernetes, OpenShift)Hilfsprozesse wie Sidecar Container auf Cloud Plattformen (Kubernetes, OpenShift)Hilfsprozesse wie Sidecar Container auf Cloud Plattformen (Kubernetes, OpenShift)Hilfsprozesse wie Sidecar Container auf Cloud Plattformen (Kubernetes, OpenShift) Systemnahe Infrastrukturdienste wie Reverse Proxies, Authentication ProxiesSystemnahe Infrastrukturdienste wie Reverse Proxies, Authentication ProxiesSystemnahe Infrastrukturdienste wie Reverse Proxies, Authentication ProxiesSystemnahe Infrastrukturdienste wie Reverse Proxies, Authentication Proxies Automationsfunktionalität in der Cloud wie Elastic Scaling AutomationAutomationsfunktionalität in der Cloud wie Elastic Scaling AutomationAutomationsfunktionalität in der Cloud wie Elastic Scaling AutomationAutomationsfunktionalität in der Cloud wie Elastic Scaling Automation Aggregator Dienste wie Backend for Frontend MicroservicesAggregator Dienste wie Backend for Frontend MicroservicesAggregator Dienste wie Backend for Frontend MicroservicesAggregator Dienste wie Backend for Frontend Microservices Infrastruktur Dienste wie Monitoring, Logging ...Infrastruktur Dienste wie Monitoring, Logging ...Infrastruktur Dienste wie Monitoring, Logging ...Infrastruktur Dienste wie Monitoring, Logging ... 47474747
  46. 46. Für welche Anwendungen sollte man Java wählen?Für welche Anwendungen sollte man Java wählen?Für welche Anwendungen sollte man Java wählen?Für welche Anwendungen sollte man Java wählen? Anwendungen mit komplexen SchnittstellenAnwendungen mit komplexen SchnittstellenAnwendungen mit komplexen SchnittstellenAnwendungen mit komplexen Schnittstellen Große Enterprise Anwendungen mit langer Lebensdauer (Standards !)Große Enterprise Anwendungen mit langer Lebensdauer (Standards !)Große Enterprise Anwendungen mit langer Lebensdauer (Standards !)Große Enterprise Anwendungen mit langer Lebensdauer (Standards !) Anwendungen mit einem hohen Wiederverwendungspotential durch vorhandene OpenAnwendungen mit einem hohen Wiederverwendungspotential durch vorhandene OpenAnwendungen mit einem hohen Wiederverwendungspotential durch vorhandene OpenAnwendungen mit einem hohen Wiederverwendungspotential durch vorhandene Open Source ProjekteSource ProjekteSource ProjekteSource Projekte 48484848
  47. 47. Die Grauzone hängt von den Entwicklern und Strategie abDie Grauzone hängt von den Entwicklern und Strategie abDie Grauzone hängt von den Entwicklern und Strategie abDie Grauzone hängt von den Entwicklern und Strategie ab Entwickler die bisher C++ und Java programmiert haben werden Go mögen und schnellEntwickler die bisher C++ und Java programmiert haben werden Go mögen und schnellEntwickler die bisher C++ und Java programmiert haben werden Go mögen und schnellEntwickler die bisher C++ und Java programmiert haben werden Go mögen und schnell produktiv seinproduktiv seinproduktiv seinproduktiv sein Entwickler die bisher nur Java programmiert haben sollten mit Go eher vorsichtig seinEntwickler die bisher nur Java programmiert haben sollten mit Go eher vorsichtig seinEntwickler die bisher nur Java programmiert haben sollten mit Go eher vorsichtig seinEntwickler die bisher nur Java programmiert haben sollten mit Go eher vorsichtig sein Firmen die sich stark in Richtung Cloud Nativer Entwicklung orientieren sollten mit GoFirmen die sich stark in Richtung Cloud Nativer Entwicklung orientieren sollten mit GoFirmen die sich stark in Richtung Cloud Nativer Entwicklung orientieren sollten mit GoFirmen die sich stark in Richtung Cloud Nativer Entwicklung orientieren sollten mit Go mutiger seinmutiger seinmutiger seinmutiger sein 49494949
  48. 48. Was kann man als Java Programmierer von Go lernen?Was kann man als Java Programmierer von Go lernen?Was kann man als Java Programmierer von Go lernen?Was kann man als Java Programmierer von Go lernen? Message Passing ist mit Java auch ohne native Channels und Go Routinen möglich. HierMessage Passing ist mit Java auch ohne native Channels und Go Routinen möglich. HierMessage Passing ist mit Java auch ohne native Channels und Go Routinen möglich. HierMessage Passing ist mit Java auch ohne native Channels und Go Routinen möglich. Hier kann man von Go und der Einfachheit der Nutzung lernen.kann man von Go und der Einfachheit der Nutzung lernen.kann man von Go und der Einfachheit der Nutzung lernen.kann man von Go und der Einfachheit der Nutzung lernen. KISS ist relevant. In Java ist inzwischen möglich ähnlich komplexen Code zu schreiben wieKISS ist relevant. In Java ist inzwischen möglich ähnlich komplexen Code zu schreiben wieKISS ist relevant. In Java ist inzwischen möglich ähnlich komplexen Code zu schreiben wieKISS ist relevant. In Java ist inzwischen möglich ähnlich komplexen Code zu schreiben wie früher in C++. Guter Java Code beschränkt sich auf das wesentliche. Es ist nichtfrüher in C++. Guter Java Code beschränkt sich auf das wesentliche. Es ist nichtfrüher in C++. Guter Java Code beschränkt sich auf das wesentliche. Es ist nichtfrüher in C++. Guter Java Code beschränkt sich auf das wesentliche. Es ist nicht zielführend jedes Java Feature in eine Anwendung einzubauen!zielführend jedes Java Feature in eine Anwendung einzubauen!zielführend jedes Java Feature in eine Anwendung einzubauen!zielführend jedes Java Feature in eine Anwendung einzubauen! Semantik Versioning und Minimal Version Detection sind Konzepte die sich auch mit JavaSemantik Versioning und Minimal Version Detection sind Konzepte die sich auch mit JavaSemantik Versioning und Minimal Version Detection sind Konzepte die sich auch mit JavaSemantik Versioning und Minimal Version Detection sind Konzepte die sich auch mit Java Tools umsetzen lassen.Tools umsetzen lassen.Tools umsetzen lassen.Tools umsetzen lassen. Es lassen sich mit ein wenig Erfahrung auch kleine, cloudfähige Java Container bauen.Es lassen sich mit ein wenig Erfahrung auch kleine, cloudfähige Java Container bauen.Es lassen sich mit ein wenig Erfahrung auch kleine, cloudfähige Java Container bauen.Es lassen sich mit ein wenig Erfahrung auch kleine, cloudfähige Java Container bauen. Hier kann man sich an Go orientieren.Hier kann man sich an Go orientieren.Hier kann man sich an Go orientieren.Hier kann man sich an Go orientieren. Man sollte sich im Projekt überlegen, was man aus Java alles weglassen kann ohne anMan sollte sich im Projekt überlegen, was man aus Java alles weglassen kann ohne anMan sollte sich im Projekt überlegen, was man aus Java alles weglassen kann ohne anMan sollte sich im Projekt überlegen, was man aus Java alles weglassen kann ohne an Produktivität und Spass zu verlieren.Produktivität und Spass zu verlieren.Produktivität und Spass zu verlieren.Produktivität und Spass zu verlieren. 50505050
  49. 49. 51515151
  50. 50. Literatur und LinksLiteratur und LinksLiteratur und LinksLiteratur und Links Die Autoren von GoDie Autoren von GoDie Autoren von GoDie Autoren von Go de.wikipedia.org/wiki/Ken_Thompsonde.wikipedia.org/wiki/Ken_Thompsonde.wikipedia.org/wiki/Ken_Thompsonde.wikipedia.org/wiki/Ken_Thompsonde.wikipedia.org/wiki/Ken_Thompsonde.wikipedia.org/wiki/Ken_Thompsonde.wikipedia.org/wiki/Ken_Thompson(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson)(https://de.wikipedia.org/wiki/Ken_Thompson) de.wikipedia.org/wiki/Rob_Pikede.wikipedia.org/wiki/Rob_Pikede.wikipedia.org/wiki/Rob_Pikede.wikipedia.org/wiki/Rob_Pikede.wikipedia.org/wiki/Rob_Pikede.wikipedia.org/wiki/Rob_Pikede.wikipedia.org/wiki/Rob_Pike(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike)(https://de.wikipedia.org/wiki/Rob_Pike) Entstehung von GoEntstehung von GoEntstehung von GoEntstehung von Go talks.golang.org/2015/gophercon-goevolution.slidetalks.golang.org/2015/gophercon-goevolution.slidetalks.golang.org/2015/gophercon-goevolution.slidetalks.golang.org/2015/gophercon-goevolution.slidetalks.golang.org/2015/gophercon-goevolution.slidetalks.golang.org/2015/gophercon-goevolution.slidetalks.golang.org/2015/gophercon-goevolution.slide(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide)(https://talks.golang.org/2015/gophercon-goevolution.slide) www.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQg(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)www.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQg(https://www.youtube.com/watch?v=0ReKdcpNyQg)www.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQg(https://www.youtube.com/watch?v=0ReKdcpNyQg)www.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQg(https://www.youtube.com/watch?v=0ReKdcpNyQg)www.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQgwww.youtube.com/watch?v=0ReKdcpNyQg(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg)(https://www.youtube.com/watch?v=0ReKdcpNyQg) WerkzeugeWerkzeugeWerkzeugeWerkzeuge golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)(https://golang.org/pkg/net/http/pprof)(https://golang.org/pkg/net/http/pprof)(https://golang.org/pkg/net/http/pprof)(https://golang.org/pkg/net/http/pprof)(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof)golang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprofgolang.org/pkg/net/http/pprof(https://golang.org/pkg/net/http/pprof) github.com/uber/go-torchgithub.com/uber/go-torchgithub.com/uber/go-torchgithub.com/uber/go-torchgithub.com/uber/go-torchgithub.com/uber/go-torchgithub.com/uber/go-torch(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch)(https://github.com/uber/go-torch) ConcurrencyConcurrencyConcurrencyConcurrency talks.golang.org/2012/concurrency.slidetalks.golang.org/2012/concurrency.slidetalks.golang.org/2012/concurrency.slidetalks.golang.org/2012/concurrency.slidetalks.golang.org/2012/concurrency.slidetalks.golang.org/2012/concurrency.slidetalks.golang.org/2012/concurrency.slide(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide)(https://talks.golang.org/2012/concurrency.slide) 52525252
  51. 51. Thank youThank youThank youThank you Johannes WeigendJohannes WeigendJohannes WeigendJohannes Weigend QAware GmbHQAware GmbHQAware GmbHQAware GmbH johannes.weigend@qaware.dejohannes.weigend@qaware.dejohannes.weigend@qaware.dejohannes.weigend@qaware.dejohannes.weigend@qaware.dejohannes.weigend@qaware.dejohannes.weigend@qaware.de(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de)(mailto:johannes.weigend@qaware.de) @jweigend@jweigend@jweigend@jweigend(http://twitter.com/jweigend)(http://twitter.com/jweigend)(http://twitter.com/jweigend)(http://twitter.com/jweigend)(http://twitter.com/jweigend)(http://twitter.com/jweigend)(http://twitter.com/jweigend)(http://twitter.com/jweigend)(http://twitter.com/jweigend)(http://twitter.com/jweigend)

×