Reading Notes on https://time.geekbang.org/column/75

My Pre-read: Netty in Action it is fairly important to understand what is Netty before looking into gRPC internals.

「grpc」的圖片搜尋結果

01 | Introduction to gRPC & How gRPC server works

  1. Multi-language support: gRPC from Google, Thrift from Facebook
  2. Limited language support: Motan
  3. Distributed service framework: Dubbo

gRPC is a high performant, OSS and general purpose RPC framework based on HTTP/2.

gRPC invocation:

  1. Language neutral: multi-language support
  2. IDL based. Code generation via proto3.
  3. Base on HTTP/2, support bidirectional flow, header compression, TCP multiplex, server push etc.
  4. Support for Protocol Buffer & JSON.
  1. gRPC init NettyServer (base on Netty 4.1 HTTP/2).
  2. Server registers API implementations generated from proto tool to its internal service registry and when requests come in, it invokes registered service instance by searching service name & method name instead of via reflection, which makes performance even better.
  3. gRPC server impl invokes NettyServer’s start method to start HTTP/2 server and receive user requests.
  1. Netty 4.1 provides HTTP/2 support. gRPC implements Http2ConnectionHandler to manage messages from HTTP/2.
  2. gRPC uses NioEventLoopGroup to avoid resources overload.

02 | How gRPC Client Works

gRPC sits on top of HTTP/2 and is an application layer protocol. In client side, it creates HTTP/2 client based on Netty, provides load balance and is responsible for request handling.

  1. Client init a RPC invocation.
  2. Resolve host address via DnsNameResolver and use LoadBalancer to select one of the available gRPC server instance.
  3. Serialize PB and leverage HTTP/2 stream to send to gRPC server.
  4. Deserialize PB response.
  5. Invoke set(Response) method in GrpcFuture an invoke blocking client thread.
  1. Server supports HTTP/2, saves the cost of protocol upgrade.
  2. Use HTTP/1.1 for protocol negotiation and upgrade afterwards.
  3. TlsNegotiator. This is built directly on top of TLS and uses ALPN extension for negotiation. It uses ‘h2’ as protocol marker.

How Netty sets up connection for HTTP/2

Two types of load balancing

  1. Server side LB (external LB, delegation LB)
  2. Client side LB (internal LB & algo implemented in client side)

An example of external LB:

Pros of this architecture is client side doesn’t have to implement LB algorithms nor maintain server list. This also benefits network isolation.

Example of client side LB:

By default, gRPC uses client side LB and provides mechanisms to extend.

03 | gRPC Thread Model Analysis

This was discussed in the Netty In Action reading notes, this is a typical NIO Reactor pattern:

The performance of RPC framework depends on 3 key factors:

  1. I/O model. BIO/NIO or AIO.
  2. Protocol. Rest + JSON or binary TCP protocol.
  3. Thread model. Where are decoding/encoding performed.

HTTP/2 server creation, request handling are handled by netty and de/serialization is handled by gRPC’s SerializingExecutor thread pool.

04 | How gRPC Service Call Works

A couple common service call mechanisms:

  1. Synchronous call.
  2. Parallelized service call.
  3. Aynschronous service call.
  1. Normal RPC call: request and respond.
  2. Streaming call base on HTTP/2. Make it possible that server(or client) can reply with multiple responses (like 1000 feed items, batch by batch).

05 | gRPC Security Design

Cross networking boundary communications should be transmitted through TLS/SSL.

If only a portion of the transmitted data has sensitive data, we can also only encrypt that portion of data:

This can be easy achieved with Netty Handler.

There are a couple ways of performing identity authentication: HTTP Basic Authentication, OAuth2, Token etc. An example of Token authentication:

A common approach is OAuth 2.0 based authentication:

  1. Client request Resource Owner for authentication (w/ username, password, etc..)
  2. Resource Owner authenticate base on the information provided and assign auth token to the client.
  3. Client uses token from step 2 and request access token from Authorization Server.
  4. Authorization Server issues access token once validated.
  5. Client carries access token to its RPC call to backend resources.
  6. Backend services validate access token for acess.
  7. If access token passes validation, Resource server returns information to the client.

Use SHA & MAC.

  1. Channel Auth. Default provides TLS based on HTTP/2.
  2. Invocation Auth. Credentials are added to the message headers for each RPC invocation.
  3. Combo Auth. 1 + 2.
  4. Google OAuth 2.0. When you access Google API with gRPC, it uses Service Accounts key to request for access token.

06 | gRPC Serialization

java.io.Serializable

Cons:

  1. can’t cross languages.
  2. not performant.

Thrift

Pros:

  1. Support tons of languages
  2. The IDL is super powerful
  3. Provides forward compatibility

Cons:

  1. Changes in data structure requires editing IDL file, regenerate code.

MessagePack

An efficient binary protocol.

Proto Buffers

Mature, cross platform/language/effective/performant and forward compatibility.

Proto Buffers is supported in Netty. You just need to add Codec Handler to the ChannelPipeline.

Diagram:

  1. Use builder pattern to set key-values based on ProtoBuf generated code and set up a message
  2. Serialize message in 1) and create a ProtoInputStream.
  3. Create NettyClientStream and gRPC HTTP/2 headers.
  4. Wrap serialized message into SendGrpcFrameCommand and send through Netty’s NIO thread.
  5. gRPC’s NettyClientHandler incepts the write request and uses Http2ConnectionEncoder to send it out through Netty’s HTTP/2 protocol stack.

End of Story

hacker, lifetime learner