Download presentation
Presentation is loading. Please wait.
Published byWade Goldie Modified over 9 years ago
1
Пишем функциональное, надежное и быстрое веб-приложение на Go
Дмитрий Вьюков, Google
2
План Зачем новый язык? Привет, Мир! Пишем веб-приложение
Инструментарий
3
История Конец 2007: Rob Pike, Ken Thompson и RobertGriesemer начали проектировать Ноябрь 2009: open-source release Март 2012: релиз Go1 Go1.1, Go1.2, Go1.3
4
Зачем? Дизайн мотивирован нашими нуждами в Google: Large-scale системы
Время сборки Эффективность Масштабируемость Concurrency Безопасность
5
Что такое Go? Простой язык, который легко изучить и читать
Статически-типизированный, но “чувствуется” как динамический Компилируется в машинный код, но быстрая разработка Быстрый и масштабируемый Сборка мусора Встроенная поддержка concurrency Стандартная библитека “с включенными батарейками” Open-source (400+ контрибьюторов)
6
Кто использует? Google: dl.google.co Google: vitess (MySQL scaling)
Google: flywheel (mobile proxy) BBC Worldwide Canonical Heroku Nokia SoundCloud Apple Yandex BitBucket dotCloud github gov.uk Heroku Intel Iron.io Mozilla Percona Zynga Docker Packer
7
Крэш-курс
8
Привет, Мир! package main import "fmt" func main() {
fmt.Printf("Привет, Мир!\n") }
9
Привет, Net! func main() {
ln, err := net.Listen("tcp", "localhost:11500") if err != nil { log.Fatal(err) } for { c, err := ln.Accept() fmt.Fprintf(c, "Привет, Net!\n") c.Close()
10
Интерфейсы fmt.Fprintf(c, "Привет, Net!\n") Duck typing!
type Writer interface { Write(p []byte) (n int, err error) } type netFD struct {...} func (fd *netFD) Write(p []byte) (nn int, err error)
11
Эхо-сервер func main() {
ln, err := net.Listen("tcp", "localhost:11500") if err != nil { log.Fatal(err) } for { c, err := ln.Accept() io.Copy(c, c)
12
Привет, concurrency! func main() {
ln, err := net.Listen("tcp", "localhost:11500") if err != nil { log.Fatal(err) } for { c, err := ln.Accept() go io.Copy(c, c)
13
Сoncurrency Горутины: go doFoo(a, b) go conn.Handle() go func() { }()
notifyCompletion() }()
14
Channels Каналы: c := make(chan int) c <- 42 fmt.Println(<-c)
15
Select select { case inChan <- v: fmt.Println("Отправлено")
case <-timeoutChan: fmt.Println("Потрачено") }
16
Запрос нескольких бэкендов
func multiGet(urls []string) (results []*http.Response) { res := make(chan *http.Response) for _, url := range urls { go func(url string) { resp, _ := http.Get(url) res <- resp }(url) } for _ = range urls { results = append(results, <-res) return
17
Запрос с таймаутом t := time.After(time.Second) for _ = range urls {
select { case resp := <-res: results = append(results, resp) case <-t: return }
18
Файловер func getFailover(primary, secondary string) *http.Response {
res := make(chan *http.Response, 1) go func() { res <- requestServer(primary) }() select { case resp := <-res: return resp case <-time.After(50 * time.Millisecond): } res <- requestServer(secondary) return <-res
19
Батарейки включены encoding/{json, xml, gob, base64}
compress/{gzip, bzip2, flate} crypto/{aes, des, sha1, tls, x509} net/{http, rpc, smtp} database/sql html/template regexp flag
20
В бой!
21
Флаги package main import "flag" var (
httpAddr = flag.String("http", ":8080", "address to serve http") apiAddr = flag.String("api", ":8081", "address to serve api") ) func main() { flag.Parse() ...
22
HTTP сервер import "net/http" func main() { ...
http.HandleFunc("/", handleWelcome) http.HandleFunc("/chat", handleChat) go http.ListenAndServe(*httpAddr, nil)
23
Websocket сервер import "code.google.com/p/go.net/websocket"
func main() { ... http.Handle("/ws", websocket.Handler(handleWebsocket))
24
API сервер import "net" func main() { ...
ln, err := net.Listen("tcp", *apiAddr) if err != nil { log.Fatal(err) } go func() { for { c, err := ln.Accept() go handleApi(c) }()
25
Бизнес логика type Message struct { From string Text string }
type Client interface { Send(m Message) var ( clients = make(map[Client]bool) clientsMutex sync.Mutex )
26
Бизнес логика (2) func registerClient(c Client) { clientsMutex.Lock()
clients[c] = true clientsMutex.Unlock() } func unregisterClient(c Client) { delete(clients, c)
27
Бизнес логика (3) func broadcastMessage(m Message) {
clientsMutex.Lock() for c := range clients { c.Send(m) } clientsMutex.Unlock()
28
HTML шаблоны var chatPageTempl = template.Must(template.New("").Parse(` <html> <body> <b>Hi, {{.Name}}!</b> <form> <input type="text" id="chattext"></input> <input type="button" value="Say" onclick="sendMessage()"></input> </form> <textarea readonly=1 rows=20 id="alltext"></textarea> </body> </html> `))
29
HTTP обработчики func handleChat(w http.ResponseWriter, r *http.Request) { name := r.FormValue("name") log.Printf("serving chat page for '%v'", name) type Params struct { Name string } chatPageTempl.Execute(w, &Params{name})
30
Websocket обработчик type WSClient struct { conn *websocket.Conn
enc *json.Encoder } func (c *WSClient) Send(m Message) { c.enc.Encode(m)
31
Websocket обработчик (2)
func handleWebsocket(ws *websocket.Conn) { c := &WSClient{ws, json.NewEncoder(ws)} registerClient(c) dec := json.NewDecoder(ws) for { var m Message if err := dec.Decode(&m); err != nil { log.Printf("error reading from websocket: %v", err) break } broadcastMessage(m) unregisterClient(c)
32
Демо
33
Инструментарий
34
Сборка Нулевая конфигурация, нет MAKEFILE $ go run myprog.go
$ go build myprog $ go get code.google.com/p/go.new/websocket
35
Пишем код $ go fmt mysource.go $ go vet - статический анализ кода
$ godoc - документация goimports/gocode/oracle: поддержка IDE
36
Тестируем $ go test $ go test -cover $ go test -race
Информативные крэш-репорты
37
Оптимизируем $ go test -bench $ go test -bench -cpu=1,2,4
$ go test -benchmem $ go test -cpuprofile $ go test -memprofile $ go test -blockprofile
38
Оптимизируем (2) - Профайлер горутин - Трейсер GC
- Трейсер планировщика - Трейсер аллокатора памяти - Статистика аллокатора памяти - Дамп кучи
39
Мониторинг import "expvar" var (
expMsgRecv = expvar.NewInt("msg_recv") expMsgSend = expvar.NewInt("msg_send") ) func broadcastMessage(m Message) { ... expMsgRecv.Add(1) expMsgSend.Add(int64(len(clients))) }
40
Что дальше? http://golang.org http://tour.golang.org golang-nuts@
Книги: An Introduction to Programming in Go Network Programming with Go Programming in Go: Creating Applications for the 21st Century
41
Другие доклады по Go 16:35 Common: Go: аналитика Рунета в реальном времени 17:45 Python: Go на Google App Engine - просто, надёжно, быстро и недорого. 19:30 Python: Juju и MaaS - эффективные инструменты развёртывания масштабных систем на "железе" и в "облаках".
42
Q&A Спасибо! Дмитрий Вьюков,
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.