Software as a service usando
Go
Andrews Medina
Who Am I
● Desenvolvedor na Globo.com desde 2008
● Criado de projetos open source como Splinter e tsuru
tsuru.io
tsuru.io
● Torna deploys rápidos e simples
● Suporta Go, Ruby, Python, PHP, Java…
● Open source
tsuru.io
$ tsuru app-deploy -a myapp -i dockerimage
tsuru.io
$ tsuru app-deploy -a myapp -i grafana/grafana
Go
● Começou em 2007 por Robert Griesemer, Ken Thompson, and Rob Pike
● Aberta em 2009
Quem usa Go?
Quem usa Go?
Hello World!
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界!")
}
motivação
Escalar maquinas
Rápida e eficiente para
computadores
Tipagem estática
var users []User
Compilada
$ go build
./main
Suporte a concorrência
Goroutines
go sort(s[:i])
go sort(s[i:])
Goroutines
go sort(s[:i])
go sort(s[i:])
Canais
func compute(ch chan int) {
ch <- someComputation()
}
func main() {
ch := make(chan int)
go compute(ch)
result := <-ch
}
Canais
func compute(ch chan int) {
ch <- someComputation()
}
func main() {
ch := make(chan int)
go compute(ch)
result := <-ch
}
Divertida e rápida para
os seres humanos
Linguagem enxuta
e simples
Inferência de tipos
numbers := int{1, 2, 3}
Interfaces e duck typing
type Closes interface {
Close()
}
Biblioteca padrão rica
● Encoding (json, xml)
● http
● html (template)
● image
● crypto
http
func main() {
http.HandleFunc("/hello", handleHello)
http.ListenAndServe("localhost:7777", nil)
}
func handleHello(w http.ResponseWriter, req *http.Request) {
fmt.Fprintln(w, "Hello, 世界!")
}
http + encoding
type user struct {
Name string
}
func userHandler (w http.ResponseWriter, r *http.Request) {
u := user{Name: “andrews”}
b, err := json.Marshal(u)
if err != nil {
panic(err)
}
w.Write(b)
}
Compilação rápida
$ go build
./main
Cross compilation
$ GOOS=linux GOARCH=amd64 go build
./main
gofmt
$ gofmt
gofmt
func main() {
http.HandleFunc("/hello", handleHello)
http.ListenAndServe("localhost:7777", nil)
}
gofmt
func main() {
http.HandleFunc("/hello", handleHello)
http.ListenAndServe("localhost:7777", nil)
}
race detector
$ go (run|test) -race
race detector
func main() {
start := time.Now()
var t *time.Timer
t = time.AfterFunc(randomDuration(), func() {
t.Reset(randomDuration())
})
time.Sleep(5 * time.Second)
}
func randomDuration() time.Duration {
return time.Duration(rand.Int63n(1e9))
}
race detector
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x8 pc=0x41e38a]
goroutine 4 [running]:
time.stopTimer(0x8, 0x12fe6b35d9472d96)
src/pkg/runtime/ztime_linux_amd64.c:35 +0x25
time.(*Timer).Reset(0x0, 0x4e5904f, 0x1)
src/pkg/time/sleep.go:81 +0x42
main.func·001()
race.go:14 +0xe3
created by time.goFunc
src/pkg/time/sleep.go:122 +0x48
race detector
==================
WARNING: DATA RACE
Read by goroutine 5:
main.func·001()
race.go:14 +0x169
Previous write by goroutine 1:
main.main()
race.go:15 +0x174
Goroutine 5 (running) created at:
time.goFunc()
src/pkg/time/sleep.go:122 +0x56
timerproc()
src/pkg/runtime/ztime_linux_amd64.c:181 +0x189
==================
profiling
● Profiler de memória e cpu
● Benchmarks automatizados
Go na Globo.com
tsuru.io
tsuru
● ~300 deploys por dia
● ~800 aplicações
● ~1400 units
tsuru
● Api REST
● Command line interface
● agents
tsuru (vantagens)
● Baixo overhead
● Cross compile (windows, linux, mac)
● Performance, no-blocking I/O, concorrência e paralelismo
tsuru (vantagens)
● Debug tools
● Padrão (gofmt, govet)
● Race detector (go test -race)
ID
● Api REST
ID (vantagens)
● Performance
● Simplicidade
Cartola
● Api REST
● Command line interface
● agents
Cartola
● 7 milhões de jogadores
● 500 mil simultâneos
Cartola
● Api REST
● Processamento em background
Cartola
● Performance sem precisar “escovar bits”
● Antes 24 máquinas com 24 cores
● Agora 24 máquinas com 4 cores
Simples e consistente
Fácil de aprender
Boa para máquina, boa
para humanos
Dúvidas?
● github.com/andrewsmedina
● twitter.com/andrewsmedina

InterCon 2016 - Software as a service usando Go como principal linguagem: os cases globo.com