Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building reliable and efficient services through gRPC

Building reliable and efficient services through gRPC

Slides for a presentation that describes gRPC as a tool for building reliable and efficient distributed system. The talk shares what exactly is gRPC, its background, which companies are using it and their cases. Also, shares how is the gRPC development workflow through a basic example of service implemented with it. After the example is shown the gRPC internal design, features and security. At the end, a demo and many references links are presented as well.

Gustavo Pantuza

September 21, 2019
Tweet

More Decks by Gustavo Pantuza

Other Decks in Programming

Transcript

  1. Gustavo Pantuza
    Building reliable and efficient services through gRPC

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  6. What is gRPC?

    View Slide

  7. Background
    ● General-purpose RPC infrastructure called Stubby
    Open Source

    View Slide

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

    View Slide

  9. Background
    Cloud Native
    Computing
    Foundation To Host
    gRPC from Google

    View Slide

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

    View Slide

  11. 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

    View Slide

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

    View Slide

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

    View Slide

  14. 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

    View Slide

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

    View Slide

  16. gRPC Workflow
    ● The Message Protocol

    View Slide

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

    View Slide

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

    View Slide

  19. 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

    View Slide

  20. 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

    View Slide

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

    View Slide

  22. 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

    View Slide

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

    View Slide

  24. 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

    View Slide

  25. 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

    View Slide

  26. 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

    View Slide

  27. 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())
    }
    }

    View Slide

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

    View Slide

  29. 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

    View Slide

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

    View Slide

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

    View Slide

  32. 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

    View Slide

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

    View Slide

  34. gRPC Design
    Blocking & Non-Blocking

    View Slide

  35. gRPC Design
    Cancellation & Timeout

    View Slide

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

    View Slide

  37. 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

    View Slide

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

    View Slide

  39. 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))

    View Slide

  40. 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)
    )

    View Slide

  41. Demo
    The Cheese
    SECURE Service

    View Slide

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

    View Slide

  43. 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

    View Slide

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

    View Slide

  45. Hey developers,
    please,
    play with me <3

    View Slide

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

    View Slide