go to the cloud

49
Go to the Cloud

Upload: frank-mueller

Post on 05-Dec-2014

881 views

Category:

Documents


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Go to the Cloud

Go to the Cloud

Page 2: Go to the Cloud

Frank Müller - Go to the Cloud 2

Baujahr 1965

Wohnhaft in Oldenburg

Software-Entwicklung seitmehr als 25 Jahren

Fachautor seit 1999

Frank MüllerFrank Müller — Go to the Cloud — 2/49

http://www.dpunkt.de/googlego

Page 3: Go to the Cloud

Typische Systeme heute

Betriebssystem

Datenbank

Hardware

Web Server

Mail

Message QueuesJobs

Caching

Load Balancer

Redundanz

Frank Müller — Go to the Cloud — 3/49

Page 4: Go to the Cloud

Google App Engine

Page 5: Go to the Cloud

Platform as a Service

Basis für eigene Web-Anwendungen

Bereitstellung von Diensten

Transparente Skalierung

Einfaches Deployment und Monitoring

Google App Engine • EigenschaftenFrank Müller — Go to the Cloud — 5/49

Page 6: Go to the Cloud

2008 Vorstellung für Python

2009 Erweiterung um Java

2011 Integration von Go

Aktuell Version 1.6.x

Go noch mit Status „experimentell“

Google App Engine • HistorieFrank Müller — Go to the Cloud — 6/49

Page 7: Go to the Cloud

Verarbeitung von HTTP Requests

Asynchrone Datenverarbeitung

Langlaufende Jobs

Chronologische Jobs

Google App Engine • Services für Go IFrank Müller — Go to the Cloud — 7/49

Page 8: Go to the Cloud

Schemalose Datenbank

Zugriff über Schlüssel und Abfragen

Keine Relationen, dafür Schlüsseltypen

Speicher für BLOBs

Memcache

Google App Engine • Services für Go IIFrank Müller — Go to the Cloud — 8/49

Page 9: Go to the Cloud

Nutzung von Google-Konten möglich

Mail

Persistente Verbindungen zum Client

Skalierbare Zugriffe auf URLs

Google App Engine • Services für Go IIIFrank Müller — Go to the Cloud — 9/49

Page 10: Go to the Cloud

Google Go

Page 11: Go to the Cloud

„Go hat das Ziel, die Sicherheit und Geschwindigkeit einer statisch typisierten kompilierten Sprache mit der Ausdrucksstärke und dem Komfort einer dynamisch typisierten interpretierten Sprache zu verbinden.

Zudem soll die Sprache für moderne, stark skalierende Systeme geeignet sein.“

— Rob Pike

Google Go • MotivationFrank Müller — Go to the Cloud — 11/49

Page 12: Go to the Cloud

Ken Thompson● Multics, Unix, B, Plan 9, ed, UTF-8● Turing Award

Robe Pike● Unix, Plan 9, Inferno, acme, Limbo,

UTF-8

Google Go • Bekannte VäterFrank Müller — Go to the Cloud — 12/49

Page 13: Go to the Cloud

Systemprogrammierung

Nebenläufigkeit

Statisch typisiert

Garbage Collection

Compiliert

Google Go • Kurz umrissenFrank Müller — Go to the Cloud — 13/49

Page 14: Go to the Cloud

Google Go • Einfache Struktur

package main

import ("fmt"

)

func greeting(greeting, name string) {fmt.Printf("%s, %s!\n", greeting, name)

}

func main() {hello := "Hello"world := "World"

greeting(hello, world)}

Frank Müller — Go to the Cloud — 14/49

Page 15: Go to the Cloud

Einfache Datentypen

Komplexe Datentypen

Kommunikationstypen

Funktionstypen

Interfaces und Methoden

Google Go • Flexibles TypenmodellFrank Müller — Go to the Cloud — 15/49

Page 16: Go to the Cloud

Google Go • Kein OO, aber Methoden

type Door struct { ... }

func NewDoor(width, height float64) *Door { ... }

func (d *Door) Open() { ... }

func (d *Door) Close() { ... }

func (d Door) IsOpen() bool { ... }

func (d Door) Size() (float64, float64) { ... }

func (d Door) String() string { ... }

Frank Müller — Go to the Cloud — 16/49

Page 17: Go to the Cloud

Google Go • Polymorphie über Schnittstellen

type TypeStringer interface {TypeString() string

}

type Foo int64type Bar struct { id string }

func (f Foo) TypeString() string {return "I'm a Foo (int64)."

}

func (b Bar) TypeString() string {return "I'm a Bar (struct)."

}

func TypePrint(ts TypeStringer) { ... }

Frank Müller — Go to the Cloud — 17/49

Page 18: Go to the Cloud

Goroutinen leichtgewichtiger als Threads

Threadpools für Goroutinen

Kommunikation über typisierte Channels

Channels nicht an Goroutinen gebunden

Google Go • NebenläufigkeitFrank Müller — Go to the Cloud — 18/49

Page 19: Go to the Cloud

Google Go • Einfache Nebenläufigkeit I

type Resource interface {...

}

type job struct {jobFunc JobFuncresultChan ResultChan

}

type JobFunc func(r Resource) *Resulttype ResultChan chan *Result

type Result struct {Payload interface{}Error os.Error

}

Frank Müller — Go to the Cloud — 19/49

Page 20: Go to the Cloud

Google Go • Einfache Nebenläufigkeit II

type Manager struct {resource ResourcejobChan chan *job

}

func NewManager(r Resource) *Manager {m := &Manager{r, make(chan *job)}

go m.backend()

return m}

func (m *Manager) backend() {for j := range m.jobChan {

j.resultChan <- j.jobFunc(m.resource)}

}

Frank Müller — Go to the Cloud — 20/49

Page 21: Go to the Cloud

Google Go • Einfache Nebenläufigkeit III

func (m Manager) Perform(jf JobFunc) ResultChan {j := &job{jf, make(ResultChan)}

go func() {m.jobChan <- j

}()

return j.resultChan}

func (m Manager) Stop() {close(m.jobChan)

}

Frank Müller — Go to the Cloud — 21/49

Page 22: Go to the Cloud

Google Go • Einfache Nebenläufigkeit IV

func AnyFunc(m Manager) (*AnyResult, os.Error) {rc := m.Perform(func(r Resource) *Result {

r.DoThis()r.DoThat()

return &Result{..., nil}})

... // Do something else.

result := <-rc

if result.Error != nil {return nil, result.Error

}

return result.Payload.(*AnyResult), nil}

Frank Müller — Go to the Cloud — 22/49

Page 23: Go to the Cloud

Umfangreiche Standardbibliothek● Netzwerk● Crypto● Zeichenketten● Marshalling und Encoding● I/O● Kompression● Bildverarbeitung● Reflection

Google Go • Organisation in PackagesFrank Müller — Go to the Cloud — 23/49

Page 24: Go to the Cloud

Formatierung

Testautomatisierung

Dokumentation

Installation externer Projekte

Zentrales Projektverzeichnis

Google Go • Reichhaltige WerkzeugeFrank Müller — Go to the Cloud — 24/49

Page 25: Go to the Cloud

Come Together

Page 26: Go to the Cloud

Come Together • Go und die App EngineFrank Müller — Go to the Cloud — 26/49

Page 27: Go to the Cloud

Come Together • HTTP Requests

package oop

import ("fmt""http". "appengine"

)

func init() {http.HandleFunc("/", greeting)

}

func greeting(rw http.ResponseWriter, r *http.Request) {fmt.Fprintf(rw, "Hello, OOP 2012!")

}

Frank Müller — Go to the Cloud — 27/49

Page 28: Go to the Cloud

Come Together • Rückgabe von JSON

type Address struct {...

}

func address(rw http.ResponseWriter, r *http.Request) {ctx := NewContext(r)

r.ParseForm()

id := r.FormValue("id")addr := ReadAddressById(ctx, id)

if b, err := json.Marshal(addr); err == nil {rw.Header().Set("Content-Type", "application/json")rw.Write(b)

}}

Frank Müller — Go to the Cloud — 28/49

Page 29: Go to the Cloud

Structs (Public / Annotation)

int(*), bool, string, float(*), []byte

Typen auf Basis dieser Typen

Eigene Typen für Zeit, *Key, BlobKey

Slices dieser Typen

Come Together • Nutzung des DatastoresFrank Müller — Go to the Cloud — 29/49

Page 30: Go to the Cloud

Come Together • Beispielstrukturen

type Address struct {Id stringStreet stringCity stringCountry stringPhotoKey appengine.BlobKey

}

type Customer struct {Id string `datastore:"CustomerId"`Name stringAddressKey *datastore.KeyOrderKeys []*datastore.KeyLastOrder datastore.TimeTurnover MoneyAvgTurnover Money `datastore:"-"`

}

Frank Müller — Go to the Cloud — 30/49

Page 31: Go to the Cloud

Come Together • Daten speichern

func StoreCustomerAddress(ctx Context, c *Customer, a *Address) os.Error {c.AddressKey = datastore.NewKey(ctx, "Address", a.Id,

0, nil)

if _, err := datastore.Put(ctx, c.AddressKey, a); err != nil {return err

}

kc := datastore.NewKey(ctx, "Customer", c.Id, 0, nil)

_, err := datastore.Put(ctx, kc, c)

return err}

Frank Müller — Go to the Cloud — 31/49

Page 32: Go to the Cloud

Come Together • Daten lesen

func ReadCustomerById(ctx Context, id string) (*Customer, *Address, os.Error) {k := datastore.NewKey(ctx, "Customer", id, 0, nil)c := new(Customer)a := new(Address)

if err := datastore.Get(ctx, k, c); err != nil {return nil, nil, err

}

if err := datastore.Get(ctx, c.AddressKey, a); err != nil {return nil, nil, err

}

return c, a, nil}

Frank Müller — Go to the Cloud — 32/49

Page 33: Go to the Cloud

Come Together • Transaktionen

func Book(ctx Context, fromAcc, toAcc string,amount Money) os.Error {b := func(c Context) os.Error {

if err := subtractAmount(c, fromAcc, amount); err != nil {return err

}

return addAmount(c, toAcc, amount)}

return datastore.RunInTransaction(ctx, b, nil)}

Frank Müller — Go to the Cloud — 33/49

Page 34: Go to the Cloud

x

Abfragetyp mit Filtern und Sortierung

Begrenzt auf eine Entität

Rückgabe der Daten oder Schlüssel

Abfrage der Anzahl

Alle Daten, Limitierung oder Iterator

Come Together • AbfragemöglichkeitenFrank Müller — Go to the Cloud — 34/49

Page 35: Go to the Cloud

Come Together • Daten abfragen

func QueryByTurnover(ctx Context, turnover Money, limit int) ([]*Customer, os.Error) {q := datastore.NewQuery("Customer").

Filter("Turnover >=", turnover).Order("-Turnover").Limit(limit)

cs := make([]*Customer, 0)

if _, err := q.GetAll(ctx, &cs); err != nil {return nil, err

}

return ts, nil}

Frank Müller — Go to the Cloud — 35/49

Page 36: Go to the Cloud

Verteilter Puffer im Hauptspeicher

Byte Slices und serialisierte Objekte

Ablauf kann festgelegt werden

Statistik zur Analyse

Come Together • CachingFrank Müller — Go to the Cloud — 36/49

Page 37: Go to the Cloud

Come Together • Cache lesen

func AllTagsCached(ctx Context) ([]*Tags, os.Error) {ts := make([]*Tags, 0)_, err := memcache.Gob.Get(ctx, "tags", &ts)

switch err {case memcache.ErrCacheMiss:

if ts, err = cacheTags(ctx); err != nil {return nil, err

}

return ts, nilcase nil:

return ts, nil}

return nil, err}

Frank Müller — Go to the Cloud — 37/49

Page 38: Go to the Cloud

Come Together • Cache schreiben

func cacheTags(ctx Context) ([]*Tags, os.Error) {if ts, err := ReadAllTags(ctx); err != nil {

return nil, err}

ci := &memcache.Item{Key: "tags",Object: ts,Expiration: 60,

}

if err = memcache.Gob.Set(ctx, ci); err != nil {return nil, err

}

return ts, nil}

Frank Müller — Go to the Cloud — 38/49

Page 39: Go to the Cloud

HTTP Requests ohne Antwort

Längere Verarbeitung möglich

Mehrere Warteschlangen

Versionierung der Tasks

Come Together • Task QueuesFrank Müller — Go to the Cloud — 39/49

Page 40: Go to the Cloud

Come Together • Task einstellen

func AsyncStoreDoc(ctx Context, d *Document) os.Error {if b, err := json.Marshall(d); err != nil {

return err}

task := &taskqueue.Task{Path: "/queues/store-doc",Payload: b,Header: make(http.Header),

}

task.Header.Set("Content-Type", "application/json")

_, err = taskqueue.Add(ctx, task, "store-doc")

return err}

Frank Müller — Go to the Cloud — 40/49

Page 41: Go to the Cloud

Come Together • Task verarbeiten

func storeDoc(rw http.ResponseWriter, r *http.Request) {var d Document

ctx := NewContext(r)b, err := ioutil.ReadAll(r.Body)

r.Body.Close()

if err != nil {ctx.Errorf("Can't read request body: %v", err)

} else if err = json.Unmarshal(b, &d); err != nil {ctx.Errorf("Can't unmarshal document: %v", err)

} else if err = StoreDoc(ctx, d); err != nil {ctx.Errorf("Can't store document: %v", err)

}}

Frank Müller — Go to the Cloud — 41/49

Page 42: Go to the Cloud

Come Together • Tasks ganz einfach

var delayedFunc = delay.Func("keyForFunc", myDelayedFunc)

func myDelayedFunc(ctx Context, ...) {...

}

func doSomething(rw http.ResponseWriter, r *http.Request) {ctx := NewContext(r)

...

delayedFunc.Call(ctx, arg1, arg2, ...)}

Frank Müller — Go to the Cloud — 42/49

Page 43: Go to the Cloud

Come Together • Google Accounts nutzen

func hello(rw http.ResponseWriter, r *http.Request) {ctx := NewContext(r)u := user.Current(ctx)

if u == nil {url := user.LoginURL(ctx, "/")

fmt.Fprintf(rw, `<a href="%s">Login</a>`, url)

return}

url := user.LogoutURL(ctx, "/")

fmt.Fprintf(rw, `<a href="%s">Logout</a>`, url)}

Frank Müller — Go to the Cloud — 43/49

Page 44: Go to the Cloud

Come Together • Ressourcen via HTTP laden

func fetcher(rw http.ResponseWriter, r *http.Request) {ctx := NewContext(r)client := urlfetch.Client(ctx)resp, err := client.Get("http://...")

if err != nil {http.Error(rw, err.String(),

http.StatusInternalServerError)

return}

...}

Frank Müller — Go to the Cloud — 44/49

Page 45: Go to the Cloud

Come Together • Mails senden

func mailer(rw http.ResponseWriter, r *http.Request) {ctx := NewContext(r)msg := &mail.Message{

Sender: "My App <[email protected]>",To: "[email protected]",Subject: "Thank you for your feedback",Body: feedbackText,

}

if err := mail.Send(ctx, msg); err != nil {http.Error(rw, err.String(),

http.StatusInternalServerError)

return}

}

Frank Müller — Go to the Cloud — 45/49

Page 46: Go to the Cloud

Fazit

Page 47: Go to the Cloud

Schneller Einstieg

Einfache und leistungsfähige API

Flexible Services

Produktive Programmiersprache

Transparente Skalierung

Fazit • VorteileFrank Müller — Go to the Cloud — 47/49

Page 48: Go to the Cloud

Weniger flexibel als IaaS, Rackspace oder Hosting

Einschränkungen in den Services und der API

Bindung an die Plattform im Code

Fazit • NachteileFrank Müller — Go to the Cloud — 48/49

Page 49: Go to the Cloud

Fragen?