Skip to content

Latest commit

 

History

History
84 lines (70 loc) · 4.82 KB

README(EN).md

File metadata and controls

84 lines (70 loc) · 4.82 KB

Objectives

  • Understand the concept of gRPC

RPC

img.png

  • RPC stands for Remote Procedure Calls
  • When request to other process, make a common interface instead of communicating in JSON.
  • Stub for each side is to serialize and deserialize the data

Features of gRPC

Modules

  • interface: define gRPC request and response
  • server: gRPC Server
  • client: gRPC Client(One time)

How to run

# Start gRPC server
./gradlew :server:bootRun

# Send a request using spring boot client 
./gradlew :client:bootRun

# Send a request using grpcurl
brew install grpcurl # mac
grpcurl --plaintext -d '{"name": "grpcurl"}' localhost:19090 Simple.SayHello

Deep Dive

gRPC request

  • From the server log, you can check these : HTTP2, content-type: application/grpc

2024-02-09T14:36:28.596+09:00 DEBUG 57331 --- [-worker-ELG-3-1] i.g.n.s.i.grpc.netty.NettyServerHandler : [id: 0xe34d6c07, L:/[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:56402] INBOUND HEADERS: streamId=5 headers=GrpcHttp2RequestHeaders[:path: /Simple/SayHello, :authority: localhost:19090, :method: POST, :scheme: http, te: trailers, content-type: application/grpc, user-agent: grpcurl/1.8.9 grpc-go/1.57.0, grpc-accept-encoding: gzip] padding=0 endStream=false

  • From the body, you can check the request message is serialized in binary format(protobuf)
    • '{"name": "grpcurl"}' -> length=14 bytes=00000000090a076772706375726c

2024-02-09T14:36:28.597+09:00 DEBUG 57331 --- [-worker-ELG-3-1] i.g.n.s.i.grpc.netty.NettyServerHandler : [id: 0xe34d6c07, L:/[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:56402] INBOUND DATA: streamId=5 padding=0 endStream=true length=14 bytes=00000000090a076772706375726c

  • From the response, you can check the response message is serialized in binary format(protobuf)
    • '{"message":"Hello grpcurl"}' -> length=21 bytes=00000000100a0e48656c6c6f2c206772706375726c

2024-02-09T14:36:28.600+09:00 DEBUG 57331 --- [-worker-ELG-3-1] i.g.n.s.i.grpc.netty.NettyServerHandler : [id: 0xe34d6c07, L:/[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:56402] OUTBOUND DATA: streamId=5 padding=0 endStream=false length=21 bytes=00000000100a0e48656c6c6f2c206772706375726c

  • Comparing to JSON, the binary format is more efficient in terms of size
Data Proto buf JSON
{"name": "grpcurl"} 14 bytes 23 bytes
{"message":"Hello grpcurl"} 21 bytes 32 bytes

How to stub with grpcurl

  • When using spring boot client, the stub is automatically generated by the plugin(protobuf)
  • However, when using grpcurl, there is no metadata to generate the stub
  • The grpcurl internally uses the reflection API to generate the stub
  • From the server log, you can check the reflection API is used right before the original request

Reflection API

[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:55968] INBOUND HEADERS: streamId=3 headers=GrpcHttp2RequestHeaders[:path: /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo, :authority: localhost:19090, :method: POST, :scheme: http, te: trailers, content-type: application/grpc, user-agent: grpcurl/1.8.9 grpc-go/1.57.0, grpc-accept-encoding: gzip] padding=0 endStream=false

And then the original API

[0:0:0:0:0:0:0:1]:19090 - R:/[0:0:0:0:0:0:0:1]:55968] INBOUND HEADERS: streamId=5 headers=GrpcHttp2RequestHeaders[:path: /Simple/SayHello, :authority: localhost:19090, :method: POST, :scheme: http, te: trailers, content-type: application/grpc, user-agent: grpcurl/1.8.9 grpc-go/1.57.0, grpc-accept-encoding: gzip] padding=0 endStream=false

Compare to REST

Conclusion

  • When data size is large, using gRPC can be a good choice.
  • Plus, We can utilize the features of HTTP2 by using gRPC

References