Slide 1

Slide 1 text

Gustavo Pantuza Building reliable and efficient services through gRPC

Slide 2

Slide 2 text

Agenda ● What is gRPC? ● Background ● Who is using ● gRPC Workflow ● gRPC Design ● Security ● Demo ● References

Slide 3

Slide 3 text

What is gRPC? "A high performance, open-source universal RPC framework" Project site: https://grpc.io Github: https://github.com/grpc

Slide 4

Slide 4 text

What is gRPC? ● Remote Procedure Call ● Type Safe ● Polyglot ● Binary message format ● Multiplexed connections

Slide 5

Slide 5 text

What is gRPC? A bunch of best practices gathered together to build a simple distributed systems tool My personal opinion

Slide 6

Slide 6 text

What is gRPC?

Slide 7

Slide 7 text

Background ● General-purpose RPC infrastructure called Stubby Open Source

Slide 8

Slide 8 text

Background Connect the large number of microservices running within and across our data centers

Slide 9

Slide 9 text

Background Cloud Native Computing Foundation To Host gRPC from Google

Slide 10

Slide 10 text

Who is using? "We’ve also seen a squishing and a narrowing of our latency windows" https://www.cncf.io/netflix-case-study/

Slide 11

Slide 11 text

Who is using? "Implementing GRPC/Telemetry on XR devices" https://community.cisco.com/t5/service-providers-documents/implementing-grpc-telemetry-on-xr-devices/ta-p/3393966

Slide 12

Slide 12 text

Who is using? "distribution layer is the first layer to communicate with other nodes" https://www.cockroachlabs.com/docs/stable/architecture/distribution-layer.html

Slide 13

Slide 13 text

Who is using? "more compact and efficiently serializable RPC payload" https://cilium.io/blog/grpc/

Slide 14

Slide 14 text

Who is using? "layers the best features of IDL-specified RPC onto a standard" https://linkerd.io/2017/01/11/http2-grpc-and-linkerd/#_ga=2.36853351.619173598.1561427300-69268088.1561427300

Slide 15

Slide 15 text

Who is using? https://stackshare.io/grpc

Slide 16

Slide 16 text

gRPC Workflow ● The Message Protocol

Slide 17

Slide 17 text

gRPC Workflow ● The Message Protocol Message definition protoc Compiler Python Go C++

Slide 18

Slide 18 text

syntax = "proto3"; package cheesefarm; Define the version and the package gRPC Workflow

Slide 19

Slide 19 text

syntax = "proto3"; package cheesefarm; message Cheese { int32 age = 1; CheeseType type = 2; } enum CheeseType { EMMENTAL = 0; BRIE = 1; PECORINO = 2; ROQUEFORT = 3; CANASTRA = 4; } message CheeseRequest { CheeseType type = 1; } Create your messages gRPC Workflow

Slide 20

Slide 20 text

syntax = "proto3"; package cheesefarm; message Cheese { int32 age = 1; CheeseType type = 2; } enum CheeseType { EMMENTAL = 0; BRIE = 1; PECORINO = 2; ROQUEFORT = 3; CANASTRA = 4; } message CheeseRequest { CheeseType type = 1; } service CheeseService { rpc Order(CheeseRequest) returns (Cheese); } Describe your Service interface gRPC Workflow

Slide 21

Slide 21 text

$> # Install gRPC libraries $> zypper install protobuf-devel $> apt install protobuf-compiler $> brew install protobuf Install gRPC dependencies gRPC Workflow

Slide 22

Slide 22 text

gRPC Design $> # Compile only messages with Golang $> # as target in the current directory $> protoc --go_out=. cheese.proto $> # Compile messages and services with Golang $> # as target in the current directory $> protoc --go_out=plugins=grpc:. cheese.proto Compilation time

Slide 23

Slide 23 text

$> # One new file generated: $> # . cheese.pb.go $> # Protocol Buffer message $> # and gRPC code $> ls cheese.proto cheese.pb.go Compilation Results gRPC Workflow

Slide 24

Slide 24 text

Resulted code example gRPC Workflow // protoc resulted file: cheese.pb.go // Code generated by protoc-gen-go. DO NOT EDIT. // source: cheese.proto package cheesefarm import ( context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" math "math" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type CheeseType int32

Slide 25

Slide 25 text

package main import ( "fmt" "log" "net" "os" "path/filepath" "google.golang.org/grpc" "google.golang.org/grpc/credentials" pb "github.com/pantuza/grpc/cheese" ) func main() { wd, _ := os.Getwd() certFile := filepath.Join(wd, "ssl", "cert.pem") keyFile := filepath.Join(wd, "ssl", "private.key") creds, _ := credentials.NewServerTLSFromFile(certFile, keyFile) serverAddr := fmt.Sprintf("%s:%d", pb.ADDR, pb.PORT) listen, err := net.Listen("tcp", serverAddr) if err != nil { log.Fatalf("Failed to listen: %v", err) } grpcServer := grpc.NewServer(grpc.Creds(creds)) pb.RegisterCheeseServiceServer(grpcServer, pb.NewServer()) fmt.Printf("Listening gRPC on %s\n", serverAddr) grpcServer.Serve(listen) } Server Implementation gRPC Workflow

Slide 26

Slide 26 text

package cheesefarm import ( "context" "fmt" "time" "math/rand" ) const ( ADDR string = "localhost" PORT int = 4000 ) type CheeseServer struct { } func NewServer() *CheeseServer { rand.Seed(time.Now().UnixNano()) server := &CheeseServer{} return server } func (s *CheeseServer) Order(ctx context.Context, r *CheeseRequest) (*Cheese, error) { time.Sleep(time.Duration(rand.Intn(3))*time.Second) fmt.Printf("[gRPC] Order=%s\n", r.GetType()) cheese := &Cheese{} cheese.Age = 10 cheese.Type = r.GetType() return cheese, nil } Service Implementation gRPC Workflow

Slide 27

Slide 27 text

Client Implementation gRPC Workflow package main import ( ... "google.golang.org/grpc" "google.golang.org/grpc/credentials" pb "github.com/pantuza/grpc/cheese" ) func main() { rand.Seed(time.Now().UnixNano()) wd, _ := os.Getwd() certFile := filepath.Join(wd, "ssl", "cert.pem") creds, err := credentials.NewClientTLSFromFile(certFile, "") if err != nil { log.Fatal("Error: %v", err) } serverAddr := fmt.Sprintf("%s:%d", pb.ADDR, pb.PORT) conn, err := grpc.Dial(serverAddr, grpc.WithTransportCredentials(creds)) if err != nil { log.Fatal("Fail to dial: %v", err) } defer conn.Close() client := pb.NewCheeseServiceClient(conn) ctx := context.Background() for { order := &pb.CheeseRequest{Type: pb.CheeseType(rand.Intn(100) % 5)} cheese, err := client.Order(ctx, order) if err != nil { log.Fatal("Error: %v", err) } fmt.Printf("[gRPC] Received=%s\n", cheese.GetType()) } }

Slide 28

Slide 28 text

gRPC Design Http/2 by design ● Binary payload ● Multiplexed connections ● Extensible

Slide 29

Slide 29 text

gRPC Design Streaming // From Server to Client rpc ListFeatures(Rectangle) returns (stream Feature) {} // From Client to Server rpc RecordRoute(stream Point) returns (RouteSummary) {} // Bidirectional rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} The classic pair Send() and Recv() from socket library

Slide 30

Slide 30 text

gRPC Design Server streaming // From Server to Client rpc Watch(Match) returns (stream Video) {}

Slide 31

Slide 31 text

gRPC Design Client streaming // From client to Client rpc Upload(stream chunks) returns (Done) {}

Slide 32

Slide 32 text

syntax = "proto3"; package stream; message Match { string id = 1; } message Video { bytes data = 1; string data_type = 2; string data_shape = 3; } service Soccer { rpc Watch (Match) returns (stream Video) {} } Protocol Buffer Example

Slide 33

Slide 33 text

gRPC Design Bidirectional streaming // Bidirectional rpc Chat(stream video) returns (stream video) {}

Slide 34

Slide 34 text

gRPC Design Blocking & Non-Blocking

Slide 35

Slide 35 text

gRPC Design Cancellation & Timeout

Slide 36

Slide 36 text

gRPC Design Pluggable Large distributed systems need: ● Security ● Health-checking ● Load-balancing ● Failover ● Monitoring ● Tracing ● logging Golang Interceptor example

Slide 37

Slide 37 text

gRPC Design Standardized Status Codes CODE NUMBER OK 0 CANCELLED 1 UNKNOWN 2 INVALID_ARGUMENT 3 ... ... https://github.com/grpc/grpc/blob/master/doc/statuscodes.md

Slide 38

Slide 38 text

gRPC security Supported and Authentication methods https://grpc.io/docs/guides/auth/

Slide 39

Slide 39 text

gRPC security TLS On the Server // Loads Certificate and private key certFile := filepath.Join(wd, "ssl", "cert.pem") keyFile := filepath.Join(wd, "ssl", "private.key") // Creates the credentials object creds, _ := credentials.NewServerTLSFromFile(certFile, keyFile) // Adds credentials to the gRPC server grpcServer := grpc.NewServer(grpc.Creds(creds))

Slide 40

Slide 40 text

gRPC security TLS On the Client // Loads client certficate certFile := filepath.Join(wd, "ssl", "cert.pem") creds, err := credentials.NewClientTLSFromFile(certFile, "") // Adds certficate on the connection conn, err := grpc.Dial( serverAddr, grpc.WithTransportCredentials(creds) )

Slide 41

Slide 41 text

Demo The Cheese SECURE Service

Slide 42

Slide 42 text

gRPC References ● Official project site ● Official project Repositories ● Awesome gRPC project ● Official examples for other languages ● Protocol Buffer official site

Slide 43

Slide 43 text

gRPC Golang Examples ● A simplified guide to gRPC in Golang ● gRPC Basics - Golang ● Python Quick Start ● Python gRPC official example ● A brief introduction to gRPC in Go

Slide 44

Slide 44 text

Cheese Farm example https://github.com/pantuza/grpc-golang-examples

Slide 45

Slide 45 text

Hey developers, please, play with me <3

Slide 46

Slide 46 text

Questions? Comments? https://blog.pantuza.com https://github.com/pantuza https://twitter.com/gpantuza gifts