• Like
Go to the Cloud
Upcoming SlideShare
Loading in...5
×

Go to the Cloud

  • 597 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
597
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
11
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Go to the Cloud
  • 2. Baujahr 1965Wohnhaft in OldenburgSoftware-Entwicklung seitmehr als 25 JahrenFachautor seit 1999 http://www.dpunkt.de/googlegoFrank Müller Frank Müller - Go to the Cloud 2Frank Müller — Go to the Cloud — 2/49
  • 3. Jobs Message Queues Caching Datenbank Web Server MailBetriebssystem Redundanz Hardware Load BalancerTypische Systeme heuteFrank Müller — Go to the Cloud — 3/49
  • 4. Google App Engine
  • 5. Platform as a ServiceBasis für eigene Web-AnwendungenBereitstellung von DienstenTransparente SkalierungEinfaches Deployment und MonitoringGoogle App Engine • EigenschaftenFrank Müller — Go to the Cloud — 5/49
  • 6. 2008 Vorstellung für Python2009 Erweiterung um Java2011 Integration von GoAktuell Version 1.6.xGo noch mit Status „experimentell“Google App Engine • HistorieFrank Müller — Go to the Cloud — 6/49
  • 7. Verarbeitung von HTTP RequestsAsynchrone DatenverarbeitungLanglaufende JobsChronologische JobsGoogle App Engine • Services für Go IFrank Müller — Go to the Cloud — 7/49
  • 8. Schemalose DatenbankZugriff über Schlüssel und AbfragenKeine Relationen, dafür SchlüsseltypenSpeicher für BLOBsMemcacheGoogle App Engine • Services für Go IIFrank Müller — Go to the Cloud — 8/49
  • 9. Nutzung von Google-Konten möglichMailPersistente Verbindungen zum ClientSkalierbare Zugriffe auf URLsGoogle App Engine • Services für Go IIIFrank Müller — Go to the Cloud — 9/49
  • 10. Google Go
  • 11. „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 PikeGoogle Go • MotivationFrank Müller — Go to the Cloud — 11/49
  • 12. Ken Thompson ● Multics, Unix, B, Plan 9, ed, UTF-8 ● Turing AwardRobe Pike ● Unix, Plan 9, Inferno, acme, Limbo, UTF-8Google Go • Bekannte VäterFrank Müller — Go to the Cloud — 12/49
  • 13. SystemprogrammierungNebenläufigkeitStatisch typisiertGarbage CollectionCompiliertGoogle Go • Kurz umrissenFrank Müller — Go to the Cloud — 13/49
  • 14. 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) }Google Go • Einfache StrukturFrank Müller — Go to the Cloud — 14/49
  • 15. Einfache DatentypenKomplexe DatentypenKommunikationstypenFunktionstypenInterfaces und MethodenGoogle Go • Flexibles TypenmodellFrank Müller — Go to the Cloud — 15/49
  • 16. 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 { ... }Google Go • Kein OO, aber MethodenFrank Müller — Go to the Cloud — 16/49
  • 17. type TypeStringer interface { TypeString() string } type Foo int64 type Bar struct { id string } func (f Foo) TypeString() string { return "Im a Foo (int64)." } func (b Bar) TypeString() string { return "Im a Bar (struct)." } func TypePrint(ts TypeStringer) { ... }Google Go • Polymorphie über SchnittstellenFrank Müller — Go to the Cloud — 17/49
  • 18. Goroutinen leichtgewichtiger alsThreadsThreadpools für GoroutinenKommunikation über typisierteChannelsChannels nicht an GoroutinengebundenGoogle Go • NebenläufigkeitFrank Müller — Go to the Cloud — 18/49
  • 19. type Resource interface { ... } type job struct { jobFunc JobFunc resultChan ResultChan } type JobFunc func(r Resource) *Result type ResultChan chan *Result type Result struct { Payload interface{} Error os.Error }Google Go • Einfache Nebenläufigkeit IFrank Müller — Go to the Cloud — 19/49
  • 20. type Manager struct { resource Resource jobChan 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) } }Google Go • Einfache Nebenläufigkeit IIFrank Müller — Go to the Cloud — 20/49
  • 21. 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) }Google Go • Einfache Nebenläufigkeit IIIFrank Müller — Go to the Cloud — 21/49
  • 22. 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 }Google Go • Einfache Nebenläufigkeit IVFrank Müller — Go to the Cloud — 22/49
  • 23. Umfangreiche Standardbibliothek ● Netzwerk ● Crypto ● Zeichenketten ● Marshalling und Encoding ● I/O ● Kompression ● Bildverarbeitung ● ReflectionGoogle Go • Organisation in PackagesFrank Müller — Go to the Cloud — 23/49
  • 24. FormatierungTestautomatisierungDokumentationInstallation externer ProjekteZentrales ProjektverzeichnisGoogle Go • Reichhaltige WerkzeugeFrank Müller — Go to the Cloud — 24/49
  • 25. Come Together
  • 26. Come Together • Go und die App EngineFrank Müller — Go to the Cloud — 26/49
  • 27. 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!") }Come Together • HTTP RequestsFrank Müller — Go to the Cloud — 27/49
  • 28. 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) } }Come Together • Rückgabe von JSONFrank Müller — Go to the Cloud — 28/49
  • 29. Structs (Public / Annotation)int(*), bool, string, float(*), []byteTypen auf Basis dieser TypenEigene Typen für Zeit, *Key, BlobKeySlices dieser TypenCome Together • Nutzung des DatastoresFrank Müller — Go to the Cloud — 29/49
  • 30. type Address struct { Id string Street string City string Country string PhotoKey appengine.BlobKey } type Customer struct { Id string `datastore:"CustomerId"` Name string AddressKey *datastore.Key OrderKeys []*datastore.Key LastOrder datastore.Time Turnover Money AvgTurnover Money `datastore:"-"` }Come Together • BeispielstrukturenFrank Müller — Go to the Cloud — 30/49
  • 31. 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 }Come Together • Daten speichernFrank Müller — Go to the Cloud — 31/49
  • 32. 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 }Come Together • Daten lesenFrank Müller — Go to the Cloud — 32/49
  • 33. 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) }Come Together • TransaktionenFrank Müller — Go to the Cloud — 33/49
  • 34. Abfragetyp mit Filtern und SortierungBegrenzt auf eine EntitätRückgabe der Daten oder Schlüssel xAbfrage der AnzahlAlle Daten, Limitierung oder IteratorCome Together • AbfragemöglichkeitenFrank Müller — Go to the Cloud — 34/49
  • 35. 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 }Come Together • Daten abfragenFrank Müller — Go to the Cloud — 35/49
  • 36. Verteilter Puffer im HauptspeicherByte Slices und serialisierte ObjekteAblauf kann festgelegt werdenStatistik zur AnalyseCome Together • CachingFrank Müller — Go to the Cloud — 36/49
  • 37. 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, nil case nil: return ts, nil } return nil, err }Come Together • Cache lesenFrank Müller — Go to the Cloud — 37/49
  • 38. 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 }Come Together • Cache schreibenFrank Müller — Go to the Cloud — 38/49
  • 39. HTTP Requests ohne AntwortLängere Verarbeitung möglichMehrere WarteschlangenVersionierung der TasksCome Together • Task QueuesFrank Müller — Go to the Cloud — 39/49
  • 40. 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 }Come Together • Task einstellenFrank Müller — Go to the Cloud — 40/49
  • 41. 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("Cant read request body: %v", err) } else if err = json.Unmarshal(b, &d); err != nil { ctx.Errorf("Cant unmarshal document: %v", err) } else if err = StoreDoc(ctx, d); err != nil { ctx.Errorf("Cant store document: %v", err) } }Come Together • Task verarbeitenFrank Müller — Go to the Cloud — 41/49
  • 42. 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, ...) }Come Together • Tasks ganz einfachFrank Müller — Go to the Cloud — 42/49
  • 43. 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) }Come Together • Google Accounts nutzenFrank Müller — Go to the Cloud — 43/49
  • 44. 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 } ... }Come Together • Ressourcen via HTTP ladenFrank Müller — Go to the Cloud — 44/49
  • 45. func mailer(rw http.ResponseWriter, r *http.Request) { ctx := NewContext(r) msg := &mail.Message{ Sender: "My App <my.app@mydomain.de>", To: "receiver@anydomain.de", Subject: "Thank you for your feedback", Body: feedbackText, } if err := mail.Send(ctx, msg); err != nil { http.Error(rw, err.String(), http.StatusInternalServerError) return } }Come Together • Mails sendenFrank Müller — Go to the Cloud — 45/49
  • 46. Fazit
  • 47. Schneller EinstiegEinfache und leistungsfähige APIFlexible ServicesProduktive ProgrammierspracheTransparente SkalierungFazit • VorteileFrank Müller — Go to the Cloud — 47/49
  • 48. Weniger flexibel als IaaS, Rackspaceoder HostingEinschränkungen in den Services undder APIBindung an die Plattform im CodeFazit • NachteileFrank Müller — Go to the Cloud — 48/49
  • 49. Fragen?