Slide 1

Slide 1 text

Gustavo Pantuza

Slide 2

Slide 2 text

Agenda ● What is gRPC? ● Background ● Who is using ● gRPC Workflow ● Demo 0 ● gRPC Design ● Demo 1 ● Security ● Demo 2 ● 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 $> pip install grpcio $> pip install grpcio-tools Install gRPC Python libraries gRPC Workflow

Slide 22

Slide 22 text

$> # Compile gRPC files with Python $> # as target language in $> # the current directory $> python -m grpc_tools.protoc \ -I. \ --python_out=. \ --grpc_python_out=. \ cheese.proto Compilation time gRPC Workflow

Slide 23

Slide 23 text

$> # Two new files generated: $> # 1. cheese_pb2.py $> Protocol Buffer message $> # 2. cheese_pb2_grpc.py $> gRPC Service Client/Server $> ls cheese_pb2* cheese_pb2.py cheese_pb2_grpc.py Compilation Results gRPC Workflow

Slide 24

Slide 24 text

# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! import grpc import cheese_pb2 as cheese__pb2 class CheeseServiceStub(object): # missing associated documentation comment in .proto file pass def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.Order = channel.unary_unary( '/cheesefarm.CheeseService/Order', request_serializer=cheese__pb2.CheeseRequest.SerializeToString, response_deserializer=cheese__pb2.Cheese.FromString, ) class CheeseServiceServicer(object): # missing associated documentation comment in .proto file pass def Order(self, request, context): # missing associated documentation comment in .proto file pass context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') Resulted code example gRPC Workflow

Slide 25

Slide 25 text

import grpc from concurrent import futures from time import sleep from random import randint # Imports all Protoc generated classes/code import cheese_pb2 import cheese_pb2_grpc class CheeseService(cheese_pb2_grpc.CheeseServiceServicer): """ Extends the auto generated CheeseServiceServicer class from Protoc compiler. In this class we implement the service layer code """ def Order(self, request, context): """ Simulates a Cheese Order load and returns a Cheese """ # Implementation here def main(): # gRPC server server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) # Binds our service implementation to a gRPC server through the # auto generated function add_CheeseServiceServicer_to_server cheese_pb2_grpc.add_CheeseServiceServicer_to_server(CheeseService(), server) print('Listening on localhost:4000') server.add_insecure_port('localhost:4000') server.start() # server.start() will not block, so we run a sleep-loop to keep # alive server alive until an interruption try: while True: sleep(60 * 60) # Each hour the loop continues except KeyboardInterrupt: server.stop(0) Server Implementation gRPC Workflow

Slide 26

Slide 26 text

from random import randint import grpc # Imports all Protoc generated classes/code import cheese_pb2 import cheese_pb2_grpc def main(): # gRPC channel channel = grpc.insecure_channel('localhost:4000') # create a stub (client) of our service stub = cheese_pb2_grpc.CheeseServiceStub(channel) while True: # Do cheeses orders cheese_request = cheese_pb2.CheeseRequest(type=randint(0, 4)) cheese = stub.Order(cheese_request) print("[gRPC] Received={0}".format( cheese_pb2.CheeseType.Name(cheese.type))) if __name__ == "__main__": main() Client Implementation gRPC Workflow

Slide 27

Slide 27 text

Demo 0 The Cheese Service

Slide 28

Slide 28 text

Demo 0

Slide 29

Slide 29 text

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

Slide 30

Slide 30 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 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Demo 1 The Soccer Match Service

Slide 34

Slide 34 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 Demo 1

Slide 35

Slide 35 text

class SoccerService(stream_pb2_grpc.SoccerServicer): """ Soccer Matches stream service based on gRPC """ def Watch(self, request, context): """ Returns a stream to a Match stream """ print("[gRPC] Match={0}".format(request.id)) file_path = "{0}.mp4".format(request.id) match = cv2.VideoCapture(file_path) while match.isOpened(): ret_val, frame = match.read() if not ret_val: break video = stream_pb2.Video( data=frame.tobytes(), data_type=frame.dtype.name, data_shape=str(frame.shape), ) yield video match.release() Server Implementation Demo 1

Slide 36

Slide 36 text

def main(): channel = grpc.insecure_channel('localhost:4000') stub = stream_pb2_grpc.SoccerStub(channel) match = stream_pb2.Match(id="KKNuUdn4wI4") iterator = stub.Watch(match) try: for video in iterator: frame = np.frombuffer( video.data, dtype=video.data_type ).reshape(literal_eval(video.data_shape)) cv2.imshow(match.id, frame) if cv2.waitKey(1) == 27: break # esc to quit cv2.destroyAllWindows() except grpc._channel._Rendezvous as err: print(err) sleep(3) Client Implementation Demo 1

Slide 37

Slide 37 text

Demo 1 The Soccer Match Service

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

gRPC Design Blocking & Non-Blocking

Slide 40

Slide 40 text

gRPC Design Cancellation & Timeout

Slide 41

Slide 41 text

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

Slide 42

Slide 42 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 43

Slide 43 text

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

Slide 44

Slide 44 text

gRPC security TLS On the Server # gRPC server server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) cheese_pb2_grpc.add_CheeseServiceServicer_to_server(CheeseService(), server) # Load SSL files ssl_key = open("ssl/private.key", "rb").read() ssl_cert = open("ssl/cert.pem", "rb").read() credentials = grpc.ssl_server_credentials([(ssl_key, ssl_cert)]) print('Listening on localhost:4000') server.add_secure_port('localhost:4000', credentials) server.start()

Slide 45

Slide 45 text

gRPC security TLS On the Client # Load Certificate file trusted_cert = open("ssl/cert.pem", "rb").read() credentials = grpc.ssl_channel_credentials(root_certificates=trusted_cert) # gRPC channel channel = grpc.secure_channel('localhost:4000', credentials) # create a stub (client) of our service stub = cheese_pb2_grpc.CheeseServiceStub(channel)

Slide 46

Slide 46 text

Demo 2 The Cheese SECURE Service

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

gRPC Python Examples ● A simplified guide to gRPC in Python ● gRPC Basics - Python ● Python Quick Start ● Python gRPC official example ● Tutorial – Writing your first gRPC service in Python

Slide 49

Slide 49 text

Hey developers, please, play with me <3