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

A Date with gRPC

A Date with gRPC

Pain of gRPC on Kubernetes
YWC Programmer Meetup #6

More Decks by Manatsawin Hanmongkolchai

Other Decks in Programming

Transcript

  1. Me • Manatsawin Hanmongkolchai • Architect at Wongnai - We

    build the platform for Wongnai of tomorrow • Owner at TipMe - Donate platform for streamers
  2. Today's Agenda • RPC vs REST • Brief introduction to

    gRPC • gRPC on Kubernetes • … ??
  3. try: req = requests.post("http://sealerd/documents/1/seal") except requests.HTTPError: print("Server error") return body

    = req.json() if "error" in body: print(body["error"]) return print("Seal success!!") Why this is not exception?
  4. try: req = requests.post("http://sealerd/documents/1/seal") except requests.HTTPError: print("Server error") return body

    = req.json() if "error" in body: print(body["error"]) return print("Seal success!!") How could I know there is error field? What if load balancer errors?
  5. It's not hard to solve It just more boilerplate to

    write (Or you could make it a library)
  6. syntax = "proto3"; package tipme.sealerd; service Sealerd { rpc Seal

    (SealRequest) returns (SealResponse); } message SealRequest { string path = 1; } message SealResponse { } Free API Docs, with types!
  7. # -*- coding: utf-8 -*- # Generated by the protocol

    buffer compiler. DO NOT EDIT! # source: sealerd/sealerd.proto import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='sealerd/sealerd.proto', package='tipme.sealerd', syntax='proto3', serialized_options=None, serialized_pb=_b('\n\x15sealerd/sealerd.proto\x12\rtipme.sealerd\"\x1b\n\x0bSealRequest\x12\x0c\n\x04path\x18\x01 \x01(\t\"\x0e\n\x0cSealResponse2J\n\x07Sealerd\x12?\n\x04Seal\x12\x1a.tipme.sealerd.SealRequest\x1a\x1b.tipme.sealerd.SealResponseb\x06proto3') ) _SEALREQUEST = _descriptor.Descriptor( name='SealRequest', full_name='tipme.sealerd.SealRequest', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( name='path', full_name='tipme.sealerd.SealRequest.path', index=0, number=1, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], serialized_start=40, serialized_end=67,
  8. import grpc from proto_gen.sealerd.sealerd_pb2 import SealRequest from proto_gen.sealerd.sealerd_pb2_grpc import SealerdStub

    channel = grpc.insecure_channel("sealerd:4000") client = SealerdStub(channel) result = client.Seal(SealRequest(path=path)) print(result)
  9. What you get • Exception on errors • Typed request

    & response • More efficient serialization • (Optional) Server to server verification & encryption • Connection reuse • Load balancing
  10. import requests requests.post("http://sealerd/twirp/tipme.Sealerd/Seal", json={ "key": 1, }) but… • Client

    library • Still standardized request/response/error • Send either Protobuf or JSON = easy to debug • HTTP 1.1 + Bring your own server = can integrate into existing stack • No streaming/bidirectional support (yet)