Transcript
Page 1: Skalierbare Anwendungen mit Google Go

Skalierbare Anwendungen mit Google Go

Page 2: Skalierbare Anwendungen mit Google Go

Frank Müller

Oldenburg Baujahr 1965

Entwickler Fachautor

!

[email protected] @themue

Page 3: Skalierbare Anwendungen mit Google Go

Moderne Mehrkernsysteme sind wie dieVereinigung von Flüssen

Page 4: Skalierbare Anwendungen mit Google Go

Ihre Energie gilt eseffizient zu nutzen

Page 5: Skalierbare Anwendungen mit Google Go

Hier bietet sich Google Go an

Page 6: Skalierbare Anwendungen mit Google Go

Google Go als multikulturelle Sprache

imperativ

bedingt funktional

bedingt objektorientiert

nebenläufig

Page 7: Skalierbare Anwendungen mit Google Go

❝It’s better to have a permanent income than to be fascinating.

–Oscar Wilde

Page 8: Skalierbare Anwendungen mit Google Go

Nebenläufigkeit in Go

• Leichtgewichtige Goroutines im Thread Pool

• Sehr große Anzahl gleichzeitig möglich

• Kommunikation und Synchronisation über Channels

• Vielfältige Kontrolle durch select Statement

Page 9: Skalierbare Anwendungen mit Google Go

Beispiel: Goroutines als Server

Client

Client

Client

Server

Page 10: Skalierbare Anwendungen mit Google Go

Beispiel: Lastverteilung

Worker

Worker

Master

Client

Client Worker

Page 11: Skalierbare Anwendungen mit Google Go

Netze von Goroutines

B

A

F

E 2E 1

E

E 3

C D

G

Page 12: Skalierbare Anwendungen mit Google Go

Ein Wimmeln wieim Bienenstock

Page 13: Skalierbare Anwendungen mit Google Go

Kapselung in Typen

package service !type Service struct { thisChan chan *This thatChan chan *That foo bool bar int baz string }

Page 14: Skalierbare Anwendungen mit Google Go

Konstruktoren sind Funktionen

func NewService(...) *Service { s := &Service{ thisChan: make(chan *This), thatChan: make(chan *That, 10), …, } ! // Start of the backend loop as goroutine. go s.loop() ! return s }

Page 15: Skalierbare Anwendungen mit Google Go

Endlosschleifen und select

func (s *Service) loop() { ticker := time.NewTicker(time.Second) for { select { case this := <-s.thisChan: s.doThis(this) case that := <-s.thatChan: s.doThat(that) case <-ticker.C: s.doTick() } } }

Page 16: Skalierbare Anwendungen mit Google Go

Methoden als externe Schnittstellen

func (s *Service) DoThis(data string) int { respChan := make(chan int) this := &This{data, respChan} ! s.thisChan <- this return <-respChan }

Page 17: Skalierbare Anwendungen mit Google Go

Goroutines können eigene Wege gehen …

Page 18: Skalierbare Anwendungen mit Google Go

… oder gemeinsame

Page 19: Skalierbare Anwendungen mit Google Go

Herausforderungen nebenläufiger Anwendungen

Rechenleistung nutzen

Rennen kontrollieren

Konflikte vermeiden

Probleme abfedern

Page 20: Skalierbare Anwendungen mit Google Go

Sehr naive Parallelisierung (1)

func process(in []int) []int { resultChan := make(chan int) for _, value := range in { // One goroutine per value. go processValue(value, resultChan) } out := make([]int, 0) for i := 0; i < len(in); i++ { out = append(out, <-resultChan) } return out }

Page 21: Skalierbare Anwendungen mit Google Go

Sehr naive Parallelisierung (2)

func processValue( inValue int, resultChan chan int) { // Time of result calculation depends // on value. outValue := inValue … ! resultChan <- outValue }

Page 22: Skalierbare Anwendungen mit Google Go

Verbesserung

• Index in der Verarbeitung mitführen

• Output mit richtiger Größe initialisieren

• Ergebnis gemäß Index setzen

Page 23: Skalierbare Anwendungen mit Google Go

Verbesserung (1)

func process(in []int) []int { resultChan := make(chan *result) for index, value := range in { // One goroutine per value. go processValue(index, value, resultChan) } out := make([]int, len(in)) for i := 0; i < len(in); i++ { result <- resultChan out[result.index] = result.value } return out }

Page 24: Skalierbare Anwendungen mit Google Go

Verbesserung (2)type result struct { index int value int } !func processValue( index, inValue int, resultChan chan *result) { // Time of result calculation depends // on value. outValue := inValue … ! // Send index with result. resultChan <- &result{index, outValue} }

Page 25: Skalierbare Anwendungen mit Google Go

Isolierung von Zugriffen

• Loops serialisieren Zugriffe

• Synchronisation über Channels oder Package sync

• Referenzen nur an eine Goroutine senden

• Aufteilung von Arrays und Slices

Page 26: Skalierbare Anwendungen mit Google Go

Unabhängigkeit von Goroutines

• Keine Beziehung zwischen Goroutines

• Kontrolle nur über Channels

• Externe Packages helfen

• git.tideland.biz/goas/loop

• launchpad.net/tomb

Page 27: Skalierbare Anwendungen mit Google Go

Schleifenfunktion

func (t *MyType) backendLoop(l loop.Loop) error { for { select { case <-l.ShallStop(): return nil case foo := <-t.fooChan: if err := t.processFoo(foo); err != nil { return err } case …: … } } }

Page 28: Skalierbare Anwendungen mit Google Go

Kontrolle der Schleifenfunktion

// Start of the goroutine in constructor. t.loop = loop.Go(t.backendLoop) !// Tell loop to stop. err := t.loop.Stop() !// Kill loop with passed error and wait. t.loop.Kill(myError) err := t.loop.Wait() !// Retrieve status and possible error. status, err := t.loop.Error()

Page 29: Skalierbare Anwendungen mit Google Go

Deadlocks vermeiden (Timeout)

func (t *MyType) Foo(foo *Foo) error { select { case t.fooChan <- foo: case <-time.After(timeout): return errors.New("timed out") } return nil }

Page 30: Skalierbare Anwendungen mit Google Go

Deadlocks vermeiden (Loop)

func (t *MyType) Foo(foo *Foo) error { select { case t.fooChan <- foo: case <-t.loop.IsStopping(): return errors.New("not running anymore") } return nil }

Page 31: Skalierbare Anwendungen mit Google Go

Vernetzung

Page 32: Skalierbare Anwendungen mit Google Go

Hilfreiche Packages

• net, …/http für IP und Web

• html/template, mime/… für Inhalte

• encoding/gob, …/json, …/xml für die Serialisierung

• compress/… zur Komprimierung

• crypto/… zur Verschlüsselung

Page 33: Skalierbare Anwendungen mit Google Go

Externe Packages von Google

• WebSocket, SPDY, Dict und mehr in code.google.com/p/go.net

• Weitere Crypto Packages (u.a. OpenPGP) in code.google.com/p/go.crypto

Page 34: Skalierbare Anwendungen mit Google Go

Serialisierung via JSON

type OrderItem struct { Id int `json:"ArticleNo"` Quantity int } !type Order struct { Name string Street string City string Remarks string `json:",omitempty"` Items []OrderItem }

Page 35: Skalierbare Anwendungen mit Google Go

Marshalling

order := Order{ Name: "Foo Bar", … Items: []OrderItem{{4711, 1}, {4712, 5}, …}, } !marshalledOrder, err := json.Marshal(order) if err != nil { … } !n, err := anyWriter.Write(marshalledOrder)

Page 36: Skalierbare Anwendungen mit Google Go

Unmarshalling

var order Order !err := json.Unmarshal(marshalledOrder, &order) if err != nil { … } !fmt.Printf("Name: %s\n", order.Name)

Page 37: Skalierbare Anwendungen mit Google Go

Fallbeispiel einer API

Netz und Crypto

Reflection für Dispatching

WebSockets

Serialisierung via JSON

Page 38: Skalierbare Anwendungen mit Google Go

❝Zitat hier eingeben.

–Christian BauerBildquellen 123RFiStockphotoeigene Quellen


Recommended