X-Git-Url: https://git.tokkee.org/?p=go-talk.git;a=blobdiff_plain;f=tex%2Fgo-grpc.tex;fp=tex%2Fgo-grpc.tex;h=f97072ade28cc31915eab3fdce60978066b9ecba;hp=0000000000000000000000000000000000000000;hb=05a62c0fec1c93a0905edeeb51d4a77301348af4;hpb=8e533c849e5b0053a1949dcbf98f8948a7501499 diff --git a/tex/go-grpc.tex b/tex/go-grpc.tex new file mode 100644 index 0000000..f97072a --- /dev/null +++ b/tex/go-grpc.tex @@ -0,0 +1,426 @@ +% +% Copyright (C) 2015-2016 Sebastian 'tokkee' Harl +% All rights reserved. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions +% are met: +% 1. Redistributions of source code must retain the above copyright +% notice, this list of conditions and the following disclaimer. +% 2. Redistributions in binary form must reproduce the above copyright +% notice, this list of conditions and the following disclaimer in the +% documentation and/or other materials provided with the distribution. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +% ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +% TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +% PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR +% CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +% OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +% OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +% ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +% +\documentclass[presentation]{beamer} +\uselanguage{German} + +\usetheme{tokkee} +\usefonttheme{professionalfonts} + +\setbeamercolor*{block body}{fg=black,bg=white} +\setbeamercolor*{block title}{use=titlelike,fg=titlelike.fg!80!black,bg=black!10} + +\usepackage{fontspec,xunicode,polyglossia} +\setdefaultlanguage[spelling=new]{german} + +\usepackage{graphicx} +\usepackage{xcolor} +\definecolor{darkgreen}{rgb}{0,0.39,0} + +\usepackage{listings} +\lstset{ + basicstyle=\scriptsize, + language=Go, + frame=single, + numbers=left, + keywordstyle=\bfseries\color{darkgreen}, + commentstyle=\itshape\color{blue}, + stringstyle=\color{red}, + showstringspaces=false, + backgroundcolor=\color{lightgray!25}, + literate=% + {Ö}{{\"O}}1 + {Ä}{{\"A}}1 + {Ü}{{\"U}}1 + {ß}{{\ss}}1 + {ü}{{\"u}}1 + {ä}{{\"a}}1 + {ö}{{\"o}}1, +} + +\usepackage[overlay,absolute]{textpos} + +\usepackage{tikz} +\usetikzlibrary{shadows} +\usetikzlibrary{shapes} + +\newcommand{\collectd}{\textsf{\textbf{collect}d}} + +\title{Web-Services mit Go} +\subtitle{Go-Features an Hand von Beispielen} + +\titlegraphic{} + +\copyrightinfo{\copyright{} 2015-2016 Sebastian `tokkee' Harl} + +\author[Sebastian Harl]{Sebastian `tokkee' Harl\\ + $<$sh@tokkee.org$>$} + +\date[2015-2016]{} + +\AtBeginSection[] +{ + \begin{frame} + \begin{center} + \Large + \titlebox{\secname} + \end{center} + \end{frame} +} + +\begin{document} + +\begin{frame}[plain] + \titlepage +\end{frame} + +\begin{frame}{Überblick} + \textbf{Was ist Go?} + + \textit{Go is an open source programming language that makes it easy to + build simple, reliable, and efficient software.}\\[10mm] + + \url{https://golang.org} + + \begin{tikzpicture}[remember picture,overlay] + \node[anchor=north east] at (current page.east) + {\includegraphics[width=.7\textwidth]{gopher}}; + \end{tikzpicture} +\end{frame} + +\begin{frame}{Web-Services} + \begin{itemize} + \item HTTP Frontend + \begin{itemize} + \item Viele parallele Client-Anfragen + \item Eine oder mehrere Verbindungen zu Backends + \end{itemize} + \item Backend ("`Business Logic"') + \begin{itemize} + \item Viele parallele Anfragen vom Frontend + \item Eine oder mehrere Datenbank-Verbindungen oder Interaktion mit + anderen Backends + \end{itemize} + \item Datenbank\\[3mm] + + \item[$\Rightarrow$] skalierbare Micro-Services~/ \textbf{lose + Kopplung}\\[5mm] + \end{itemize} + + \textbf{Auch:} Gleiche Prinzipien bei Integration mit anderen Lösungen +\end{frame} + +\begin{frame}{Einschub: Go Standard Bibliothek} + \url{https://golang.org/pkg/}\\[5mm] + + \begin{itemize} + \item Crypto + \item Datenbanken + \item Go Parser + \item Netzwerk, HTTP, SMTP, etc. + \item Datenstrukturen\\[7mm] + \end{itemize} + + \textbf{Mehr?} $\Rightarrow$ \url{https://godoc.org/} +\end{frame} + +\begin{frame}[fragile]{Ein Webserver} + \begin{lstlisting} +import (...) + +func main() { + http.HandleFunc("/hallo", sageHallo) + log.Fatal(http.ListenAndServe(":9999", nil)) +} + +func sageHallo(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hallo %s", r.RemoteAddr) +} +\end{lstlisting} + + \begin{itemize} + \item \url{https://golang.org/pkg/log/} + \item \url{https://golang.org/pkg/net/http/} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Ein Webserver -- Templates} + \begin{lstlisting} +var tmpl = template.Must( + template.New("results").Parse(` + +{{.Title}} + + + +

Hallo {{.Name}}

+ +`)) + \end{lstlisting} + + \begin{itemize} + \item \url{https://golang.org/pkg/html/template/} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Ein Webserver -- Templates (2)} + \begin{lstlisting} +func sageHallo(...) { + d := struct { + Title, Name string + }{"Hallo Welt", r.RemoteAddr} + + var buf bytes.Buffer + if err := tmpl.Execute(&buf, d); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + io.Copy(w, &buf) +} + \end{lstlisting} + + \begin{itemize} + \item \url{https://golang.org/pkg/bytes/} + \item \url{https://golang.org/pkg/io/} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Einschub: io.Writer} + \begin{itemize} + \item Warum funktioniert fmt.Printf, tmpl.Execute, http.Error, io.Copy + eigentlich mit dem http.ResponseWriter und bytes.Buffer? + \end{itemize} + + \begin{lstlisting} +package io +type Writer interface { + Write(p []byte) (n int, err error) +} + \end{lstlisting} + + \begin{itemize} + \item[$\Rightarrow$] \textbf{Sehr} einfaches Interface + \item[$\Rightarrow$] \texttt{http.ResponseWriter} und + \texttt{bytes.Buffer} implementieren es\\[7mm] + \end{itemize} + + Viele andere Beispiele ... +\end{frame} + +\begin{frame}[fragile]{Viele Backend-Abfragen} + \begin{lstlisting} +func Query(*Request) (*Response, error) { ... } + +func anfrage(w http.ResponseWriter, r *http.Request) { + requests := []*Request{...} + + responses := make([]*Reponse, len(requests)) + errCh := make(chan error, len(requests)) + + for i, req := range requests { + go func(i int, req *Request) { + var err error + responses[i], err = Query(req) + errCh <- err + }(i, req) + } + + // ... + \end{lstlisting} +\end{frame} + +\begin{frame}[fragile]{Viele Backend-Abfragen (2)} + \begin{lstlisting} + ... + timeout := time.After(50*time.Millisecond) + + for range requests { + select { + case err := <-errCh: + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + case <-timeout: + http.Error(w, "timeout", http.StatusRequestTimeout) + return + } + } + // Alle Ergebnisse verfügbar. + \end{lstlisting} + + \begin{itemize} + \item Siehe auch \url{https://golang.org/pkg/sync/#WaitGroup} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Spezielle Fehlerbehandlung} + \begin{lstlisting} + go func(req *Request) { + var err error + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("error while querying backend: %v", e) + } + errCh <- err + }() + + responses[i], err = Query(req) + }(req) + \end{lstlisting} +\end{frame} + +\begin{frame}{Backends -- gRPC} + \textbf{Beispiel: Backend Kommunikation~/ API}\\[5mm] + + \textit{A high performance, open source, general RPC framework that puts + mobile and HTTP/2 first.}\\[10mm] + + \url{https://grpc.io}\\ + \hfill\includegraphics[width=.3\textwidth]{grpc} +\end{frame} + +\begin{frame}{gRPC Überblick} + \url{https://github.com/google/protobuf}\\[5mm] + + \begin{itemize} + \item gRPC basiert auf Protocol Buffers + \item Unterstützung diverser Sprachen\newline + C++, Java, Go, Python, \ldots + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{gRPC Beispiel} + \begin{lstlisting}[morekeywords={syntax,service,message}] +syntax "proto3"; + +package mein_service; + +service Backend { + rpc Query(QueryRequest) return (QueryResponse); + + // ... +} + +message QueryRequest { + string query = 1; +} + +message QueryResponse { + string type = 1; + int64 n = 2; +} + \end{lstlisting} +\end{frame} + +\begin{frame}{gRPC mit Go} + \begin{itemize} + \item Die "`protobuf"' Datei muss mittels des Protobuf Compilers und einer + gRPC Compiler-Erweiterung übersetzt werden + \item Der Compiler erzeugt Go Code, welcher Interfaces und generischen + Code erzeugt + \item Das Interface entspricht im Wesentlichen der \texttt{service} + Definition + \item Das Interface muss für den Server implementiert werden + \item Generischer Client-Code sollte ausreichen\newline + $\rightarrow$ API Entwurf!\\[7mm] + \end{itemize} + + \url{https://github.com/grpc/grpc-go}\\ + \url{https://golang.org/x/net/context} +\end{frame} + +\begin{frame}[fragile]{gRPC mit Go: Server} + \begin{lstlisting} +import pb "tokkee.net/mein_service/service_proto" + +type server struct{} + +func (*server) Query(ctx context.Context, + in *pb.QueryRequest) (*pb.QueryResponse, error) { + + n, err := runQuery(in.Query) + if err != nil { + return nil, err + } + return &pb.QueryResponse{ + Type: "irgendwas", + N: n, + }, nil +} + \end{lstlisting} +\end{frame} + +\begin{frame}[fragile]{gRPC mit Go: Server (2)} + \begin{lstlisting} +func main() { + l, err := net.Listen("tcp", port) + if err != nil { + log.Fatal(err) + } + + s := grpc.NewServer() + pb.RegisterBackendServer(s, &server{}) + s.Serve(l) +} + \end{lstlisting} +\end{frame} + +\begin{frame}[fragile]{gRPC mit Go: Client} + \begin{lstlisting} +func main() { + ctx := context.Background() + + conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) + if err != nil { + log.Fatal(err) + } + defer conn.Close() + c := pb.NewBackendClient(conn) + + res, err := c.Query(ctx, &pb.QueryRequest{ + Query: "ein query", + }) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Antwort vom Typ %q: %d\n", res.Type, res.N) +} + \end{lstlisting} +\end{frame} + +\begin{frame}{\inserttitle} + \begin{center} + Danke für die Aufmerksamkeit\\[2mm] + {\Large Fragen, Kommentare?}\\[6mm] + + \url{https://golang.org}\quad—\quad + \url{https://github.com/grpc/grpc-go} + \end{center} +\end{frame} + +\end{document} + +% vim: set shiftwidth=2 softtabstop=2 tabstop=8 noexpandtab spelllang=de_de :