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.
2. 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
3. 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
5. 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
6. 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
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)
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
8. 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
9. 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
10. Go Programmierung in a NutshellGo Programmierung in a NutshellGo Programmierung in a NutshellGo Programmierung in a Nutshell
11111111
11. 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
12. 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
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 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
14. 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
15. 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
16. 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
17. 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
18. 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
19. 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
20. 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
21. 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
22. 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/gotorch/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/gotorch/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/gotorch/graph.getFormattedFunctionLabel (2,012 samples, 60.60%)
r..run..
ru..
23232323232323
24. 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
25. 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
26. 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
27. 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
28. 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
29. 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
30. 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
31. 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
32. 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
33. 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
34. 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
36. "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
37. 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
38. 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
41. 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
42. 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
43. 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
44. 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
45. 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
46. 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
47. 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
48. 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
49. 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
51. 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
52. 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)