Mastering RPC and gRPC: Concepts, Frameworks, and Hands‑On Java Demo
This article explains the fundamentals of RPC and gRPC, compares popular RPC frameworks, details gRPC's features and Protocol Buffers advantages, and provides a complete Java hands‑on example with code, project structure, and performance benchmarks.
1. RPC
1.1 What Is RPC?
RPC (Remote Procedure Call) is a protocol that aims to make remote service invocation simple and transparent.
An RPC framework hides the underlying transport (TCP/UDP), serialization (XML/JSON/binary) and communication details, allowing callers to invoke remote services as if they were local methods.
1.2 Why Use RPC?
When business logic grows and cannot be cleanly separated, common functionality can be extracted into independent services. RPC provides an efficient communication mechanism between these services.
1.3 Common RPC Frameworks
gRPC : language‑neutral, platform‑neutral open‑source RPC system originally developed by Google.
Thrift : scalable, cross‑language service framework supporting many languages.
Dubbo : distributed service framework and SOA governance solution.
Spring Cloud : a collection of projects offering tools for building distributed systems and microservices.
1.4 RPC Call Flow
The framework encapsulates network details. The typical flow includes:
Client invokes service as a local call.
Client stub assembles method and parameters into a network message.
Client stub discovers service address and sends the message.
Server stub receives and decodes the message.
Server stub invokes the local service implementation.
Service executes and returns result to server stub.
Server stub packages the result and sends it back.
Client stub receives and decodes the response.
Client obtains the final result.
RPC aims to hide steps 2‑8 from the user.
2. gRPC
2.1 What Is gRPC?
gRPC is a high‑performance, open‑source RPC framework developed by Google in 2015, built on HTTP/2 and using Protocol Buffers for serialization. It supports many programming languages.
Because it is open source, both client and server can be extended, focusing on business logic while the framework handles low‑level communication.
The data part represents business‑level content, while all other details are encapsulated by gRPC.
2.2 gRPC Features
Cross‑language support (C++, Java, Go, Python, Ruby, C#, Node.js, Android Java, Objective‑C, PHP, etc.).
Service definition via IDL files; proto3 generates language‑specific data structures, server interfaces, and client stubs.
Built on standard HTTP/2, offering bidirectional streams, header compression, multiplexing, and server push, which reduces power consumption and network traffic on mobile devices.
Supports both Protocol Buffers and JSON serialization; PB provides high‑performance binary encoding.
Simple installation and extensibility (can handle millions of RPCs per second).
2.3 gRPC Interaction Process
The switch acts as a gRPC client, the collector acts as a gRPC server.
The switch builds data in GPB/JSON format according to subscribed events, writes a proto file, establishes a gRPC channel, and sends a request.
The server decodes the proto file, reconstructs the data structure, and processes the business logic.
After processing, the server re‑encodes the response with Protocol Buffers and sends it back via gRPC.
The switch receives the response and the interaction ends.
In short, gRPC establishes a connection after both sides enable the gRPC feature and pushes subscription data from the device to the server. The process relies on Protocol Buffers to define structured data in proto files.
2.4 Protocol Buffers
ProtoBuf is a flexible, high‑efficiency data format similar to XML/JSON but optimized for performance‑critical data transmission.
In gRPC, Protocol Buffers serve three purposes: defining data structures, defining service interfaces, and improving transmission efficiency through serialization.
Binary encoding reduces payload size dramatically compared to text‑based formats, leading to faster transmission.
Compared with XML/JSON, Protocol Buffers produce binary data that is about one‑third to one‑tenth the size and can be parsed 20‑100 times faster.
Limitations: official support currently only for Java, C++, and Python; fewer data types and no dedicated RPC framework built on top of it.
Typical use cases include high‑performance internal RPC calls, cross‑company communication where low latency is required, and object persistence where compact storage is beneficial.
2.5 Design Based on HTTP 2.0
gRPC inherits HTTP 2.0 features such as multiplexing, binary frames, header compression, and server push, which reduce bandwidth, TCP connections, and CPU usage.
2.6 Performance Comparison
Binary protobuf can be up to five times faster than JSON. Benchmark results from Auth0 show protobuf request time is about 20 % of JSON’s.
Additional charts show XML serialization performs poorly, Thrift is less efficient than Protobuf, while Protobuf and Avro excel in both speed and size.
3. gRPC Hands‑On Example
3.1 Project Structure
The example project contains a Maven build that generates protobuf classes and a simple HelloWorld service.
3.2 Generating Protobuf Files
helloworld.proto defines the service and messages:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}The Maven pom.xml includes the protobuf‑maven‑plugin and gRPC dependencies.
<project ...>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.14.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.5.1-1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.14.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>3.3 Server and Client Code
Client (HelloWorldClient.java) creates a channel, builds a request, calls sayHello, and prints the response.
public class HelloWorldClient {
private final ManagedChannel channel;
private final GreeterGrpc.GreeterBlockingStub blockingStub;
private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());
public HelloWorldClient(String host, int port) {
channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext(true)
.build();
blockingStub = GreeterGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public void greet(String name) {
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloReply response;
try {
response = blockingStub.sayHello(request);
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
logger.info("Message from gRPC-Server: " + response.getMessage());
}
public static void main(String[] args) throws InterruptedException {
HelloWorldClient client = new HelloWorldClient("127.0.0.1", 50051);
try {
String user = "world";
if (args.length > 0) {
user = args[0];
}
client.greet(user);
} finally {
client.shutdown();
}
}
}Server (HelloWorldServer.java) starts a gRPC server, implements GreeterImpl with sayHello, and logs messages.
public class HelloWorldServer {
private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
private final int port = 50051;
private Server server;
private void start() throws IOException {
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.build()
.start();
logger.info("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.err.println("*** shutting down gRPC server since JVM is shutting down");
HelloWorldServer.this.stop();
System.err.println("*** server shut down");
}
});
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
final HelloWorldServer server = new HelloWorldServer();
server.start();
server.blockUntilShutdown();
}
private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
System.out.println("Message from gRPC-Client: " + req.getName());
System.out.println("Message Response: " + reply.getMessage());
}
}
}3.4 Running the Service
Start the server first; the console shows “Server started, listening on 50051”. Then run the client to see the greeting and server logs.
3.5 Source Code
The full project is available at GitHub .
4. Conclusion
This article provides a comprehensive overview of RPC and gRPC, including concepts, features, performance analysis, and a complete Java demo.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
