1 %
2 % Copyright (C) 2015-2016 Sebastian 'tokkee' Harl <sh@tokkee.org>
3 % All rights reserved.
4 %
5 % Redistribution and use in source and binary forms, with or without
6 % modification, are permitted provided that the following conditions
7 % are met:
8 % 1. Redistributions of source code must retain the above copyright
9 % notice, this list of conditions and the following disclaimer.
10 % 2. Redistributions in binary form must reproduce the above copyright
11 % notice, this list of conditions and the following disclaimer in the
12 % documentation and/or other materials provided with the distribution.
13 %
14 % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 % ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16 % TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 % PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
18 % CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 % EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 % PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 % OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 % WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 % OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 % ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 %
26 \documentclass[presentation]{beamer}
27 \uselanguage{German}
29 \usetheme{tokkee}
30 \usefonttheme{professionalfonts}
32 \setbeamercolor*{block body}{fg=black,bg=white}
33 \setbeamercolor*{block title}{use=titlelike,fg=titlelike.fg!80!black,bg=black!10}
35 \usepackage{fontspec,xunicode,polyglossia}
36 \setdefaultlanguage[spelling=new]{german}
38 \usepackage{graphicx}
39 \usepackage{xcolor}
40 \definecolor{darkgreen}{rgb}{0,0.39,0}
42 \usepackage{listings}
43 \lstset{
44 basicstyle=\scriptsize,
45 language=Go,
46 frame=single,
47 numbers=left,
48 keywordstyle=\bfseries\color{darkgreen},
49 commentstyle=\itshape\color{blue},
50 stringstyle=\color{red},
51 showstringspaces=false,
52 backgroundcolor=\color{lightgray!25},
53 literate=%
54 {Ö}{{\"O}}1
55 {Ä}{{\"A}}1
56 {Ü}{{\"U}}1
57 {ß}{{\ss}}1
58 {ü}{{\"u}}1
59 {ä}{{\"a}}1
60 {ö}{{\"o}}1,
61 }
63 \usepackage[overlay,absolute]{textpos}
65 \usepackage{tikz}
66 \usetikzlibrary{shadows}
67 \usetikzlibrary{shapes}
69 \newcommand{\collectd}{\textsf{\textbf{collect}d}}
71 \title{Web-Services mit Go}
72 \subtitle{Go-Features an Hand von Beispielen}
74 \titlegraphic{}
76 \copyrightinfo{\copyright{} 2015-2016 Sebastian `tokkee' Harl}
78 \author[Sebastian Harl]{Sebastian `tokkee' Harl\\
79 $<$sh@tokkee.org$>$}
81 \date[2015-2016]{}
83 \AtBeginSection[]
84 {
85 \begin{frame}
86 \begin{center}
87 \Large
88 \titlebox{\secname}
89 \end{center}
90 \end{frame}
91 }
93 \begin{document}
95 \begin{frame}[plain]
96 \titlepage
97 \end{frame}
99 \begin{frame}{Überblick}
100 \textbf{Was ist Go?}
102 \textit{Go is an open source programming language that makes it easy to
103 build simple, reliable, and efficient software.}\\[10mm]
105 \url{https://golang.org}
107 \begin{tikzpicture}[remember picture,overlay]
108 \node[anchor=north east] at (current page.east)
109 {\includegraphics[width=.7\textwidth]{gopher}};
110 \end{tikzpicture}
111 \end{frame}
113 \begin{frame}{Web-Services}
114 \begin{itemize}
115 \item HTTP Frontend
116 \begin{itemize}
117 \item Viele parallele Client-Anfragen
118 \item Eine oder mehrere Verbindungen zu Backends
119 \end{itemize}
120 \item Backend ("`Business Logic"')
121 \begin{itemize}
122 \item Viele parallele Anfragen vom Frontend
123 \item Eine oder mehrere Datenbank-Verbindungen oder Interaktion mit
124 anderen Backends
125 \end{itemize}
126 \item Datenbank\\[3mm]
128 \item[$\Rightarrow$] skalierbare Micro-Services~/ \textbf{lose
129 Kopplung}\\[5mm]
130 \end{itemize}
132 \textbf{Auch:} Gleiche Prinzipien bei Integration mit anderen Lösungen
133 \end{frame}
135 \begin{frame}{Einschub: Go Standard Bibliothek}
136 \url{https://golang.org/pkg/}\\[5mm]
138 \begin{itemize}
139 \item Crypto
140 \item Datenbanken
141 \item Go Parser
142 \item Netzwerk, HTTP, SMTP, etc.
143 \item Datenstrukturen\\[7mm]
144 \end{itemize}
146 \textbf{Mehr?} $\Rightarrow$ \url{https://godoc.org/}
147 \end{frame}
149 \begin{frame}[fragile]{Ein Webserver}
150 \begin{lstlisting}
151 import (...)
153 func main() {
154 http.HandleFunc("/hallo", sageHallo)
155 log.Fatal(http.ListenAndServe(":9999", nil))
156 }
158 func sageHallo(w http.ResponseWriter, r *http.Request) {
159 fmt.Fprintf(w, "Hallo %s", r.RemoteAddr)
160 }
161 \end{lstlisting}
163 \begin{itemize}
164 \item \url{https://golang.org/pkg/log/}
165 \item \url{https://golang.org/pkg/net/http/}
166 \end{itemize}
167 \end{frame}
169 \begin{frame}[fragile]{Ein Webserver -- Templates}
170 \begin{lstlisting}
171 var tmpl = template.Must(
172 template.New("results").Parse(`
173 <html><head>
174 <title>{{.Title}}</title>
175 </head>
177 <body>
178 <h1>Hallo {{.Name}}</h1>
179 </body></html>
180 `))
181 \end{lstlisting}
183 \begin{itemize}
184 \item \url{https://golang.org/pkg/html/template/}
185 \end{itemize}
186 \end{frame}
188 \begin{frame}[fragile]{Ein Webserver -- Templates (2)}
189 \begin{lstlisting}
190 func sageHallo(...) {
191 d := struct {
192 Title, Name string
193 }{"Hallo Welt", r.RemoteAddr}
195 var buf bytes.Buffer
196 if err := tmpl.Execute(&buf, d); err != nil {
197 http.Error(w, err.Error(), http.StatusInternalServerError)
198 return
199 }
200 io.Copy(w, &buf)
201 }
202 \end{lstlisting}
204 \begin{itemize}
205 \item \url{https://golang.org/pkg/bytes/}
206 \item \url{https://golang.org/pkg/io/}
207 \end{itemize}
208 \end{frame}
210 \begin{frame}[fragile]{Einschub: io.Writer}
211 \begin{itemize}
212 \item Warum funktioniert fmt.Printf, tmpl.Execute, http.Error, io.Copy
213 eigentlich mit dem http.ResponseWriter und bytes.Buffer?
214 \end{itemize}
216 \begin{lstlisting}
217 package io
218 type Writer interface {
219 Write(p []byte) (n int, err error)
220 }
221 \end{lstlisting}
223 \begin{itemize}
224 \item[$\Rightarrow$] \textbf{Sehr} einfaches Interface
225 \item[$\Rightarrow$] \texttt{http.ResponseWriter} und
226 \texttt{bytes.Buffer} implementieren es\\[7mm]
227 \end{itemize}
229 Viele andere Beispiele ...
230 \end{frame}
232 \begin{frame}[fragile]{Viele Backend-Abfragen}
233 \begin{lstlisting}
234 func Query(*Request) (*Response, error) { ... }
236 func anfrage(w http.ResponseWriter, r *http.Request) {
237 requests := []*Request{...}
239 responses := make([]*Reponse, len(requests))
240 errCh := make(chan error, len(requests))
242 for i, req := range requests {
243 go func(i int, req *Request) {
244 var err error
245 responses[i], err = Query(req)
246 errCh <- err
247 }(i, req)
248 }
250 // ...
251 \end{lstlisting}
252 \end{frame}
254 \begin{frame}[fragile]{Viele Backend-Abfragen (2)}
255 \begin{lstlisting}
256 ...
257 timeout := time.After(50*time.Millisecond)
259 for range requests {
260 select {
261 case err := <-errCh:
262 if err != nil {
263 http.Error(w, err.Error(), http.StatusBadRequest)
264 return
265 }
266 case <-timeout:
267 http.Error(w, "timeout", http.StatusRequestTimeout)
268 return
269 }
270 }
271 // Alle Ergebnisse verfügbar.
272 \end{lstlisting}
274 \begin{itemize}
275 \item Siehe auch \url{https://golang.org/pkg/sync/#WaitGroup}
276 \end{itemize}
277 \end{frame}
279 \begin{frame}[fragile]{Spezielle Fehlerbehandlung}
280 \begin{lstlisting}
281 go func(req *Request) {
282 var err error
283 defer func() {
284 if e := recover(); e != nil {
285 err = fmt.Errorf("error while querying backend: %v", e)
286 }
287 errCh <- err
288 }()
290 responses[i], err = Query(req)
291 }(req)
292 \end{lstlisting}
293 \end{frame}
295 \begin{frame}{Backends -- gRPC}
296 \textbf{Beispiel: Backend Kommunikation~/ API}\\[5mm]
298 \textit{A high performance, open source, general RPC framework that puts
299 mobile and HTTP/2 first.}\\[10mm]
301 \url{https://grpc.io}\\
302 \hfill\includegraphics[width=.3\textwidth]{grpc}
303 \end{frame}
305 \begin{frame}{gRPC Überblick}
306 \url{https://github.com/google/protobuf}\\[5mm]
308 \begin{itemize}
309 \item gRPC basiert auf Protocol Buffers
310 \item Unterstützung diverser Sprachen\newline
311 C++, Java, Go, Python, \ldots
312 \end{itemize}
313 \end{frame}
315 \begin{frame}[fragile]{gRPC Beispiel}
316 \begin{lstlisting}[morekeywords={syntax,service,message}]
317 syntax "proto3";
319 package mein_service;
321 service Backend {
322 rpc Query(QueryRequest) return (QueryResponse);
324 // ...
325 }
327 message QueryRequest {
328 string query = 1;
329 }
331 message QueryResponse {
332 string type = 1;
333 int64 n = 2;
334 }
335 \end{lstlisting}
336 \end{frame}
338 \begin{frame}{gRPC mit Go}
339 \begin{itemize}
340 \item Die "`protobuf"' Datei muss mittels des Protobuf Compilers und einer
341 gRPC Compiler-Erweiterung übersetzt werden
342 \item Der Compiler erzeugt Go Code, welcher Interfaces und generischen
343 Code erzeugt
344 \item Das Interface entspricht im Wesentlichen der \texttt{service}
345 Definition
346 \item Das Interface muss für den Server implementiert werden
347 \item Generischer Client-Code sollte ausreichen\newline
348 $\rightarrow$ API Entwurf!\\[7mm]
349 \end{itemize}
351 \url{https://github.com/grpc/grpc-go}\\
352 \url{https://golang.org/x/net/context}
353 \end{frame}
355 \begin{frame}[fragile]{gRPC mit Go: Server}
356 \begin{lstlisting}
357 import pb "tokkee.net/mein_service/service_proto"
359 type server struct{}
361 func (*server) Query(ctx context.Context,
362 in *pb.QueryRequest) (*pb.QueryResponse, error) {
364 n, err := runQuery(in.Query)
365 if err != nil {
366 return nil, err
367 }
368 return &pb.QueryResponse{
369 Type: "irgendwas",
370 N: n,
371 }, nil
372 }
373 \end{lstlisting}
374 \end{frame}
376 \begin{frame}[fragile]{gRPC mit Go: Server (2)}
377 \begin{lstlisting}
378 func main() {
379 l, err := net.Listen("tcp", port)
380 if err != nil {
381 log.Fatal(err)
382 }
384 s := grpc.NewServer()
385 pb.RegisterBackendServer(s, &server{})
386 s.Serve(l)
387 }
388 \end{lstlisting}
389 \end{frame}
391 \begin{frame}[fragile]{gRPC mit Go: Client}
392 \begin{lstlisting}
393 func main() {
394 ctx := context.Background()
396 conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
397 if err != nil {
398 log.Fatal(err)
399 }
400 defer conn.Close()
401 c := pb.NewBackendClient(conn)
403 res, err := c.Query(ctx, &pb.QueryRequest{
404 Query: "ein query",
405 })
406 if err != nil {
407 log.Fatal(err)
408 }
409 fmt.Printf("Antwort vom Typ %q: %d\n", res.Type, res.N)
410 }
411 \end{lstlisting}
412 \end{frame}
414 \begin{frame}{\inserttitle}
415 \begin{center}
416 Danke für die Aufmerksamkeit\\[2mm]
417 {\Large Fragen, Kommentare?}\\[6mm]
419 \url{https://golang.org}\quad—\quad
420 \url{https://github.com/grpc/grpc-go}
421 \end{center}
422 \end{frame}
424 \end{document}
426 % vim: set shiftwidth=2 softtabstop=2 tabstop=8 noexpandtab spelllang=de_de :