一 点睛
Protobuf 可以对消息进行编码和解码,但必须借助 Netty 等通信技术才能进行传输消息。Google 公司将 Protobuf 和 Netty 进行了结合,并在此基础上开发了一歀新的高性能的 RPC 框架——gRPC。
gRPC 是基于 HTTP/2 协议标准的,不过 HTTP/2 完全兼容 HTTP/1 的语义,因此在开发时,不用担心两种协议之间的差异。
二 gRPC 环境搭建步骤
1 访问 GitHub - grpc/grpc-java: The Java gRPC implementation. HTTP/2 based RPChttps://github.com/grpc/grpc-java下载 grpc,这里使用 v1.15.0
2 通过 Git 命令,对其进行下载
git clone -b v1.15.0 https://github.com/grpc/grpc-java
三 入门案例
以官方的 examples 中的 HelloWorld 示例进行说明。
1 protobuf 文件
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;
// 接口定义
service Greeter {
// 接口方法
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 请求消息
message HelloRequest {
string name = 1;
}
// 响应消息
message HelloReply {
string message = 1;
}
2 服务端代码
package io.grpc.examples.helloworld;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
import java.util.logging.Logger;
/**
* Hello world 的服务端
*/
public class HelloWorldServer {
private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
private Server server;
// 启动服务端
private void start() throws IOException {
/* 监听端口 */
int port = 50051;
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();
}
// 服务实现类
static 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();
}
}
}
3 客户端代码
package io.grpc.examples.helloworld;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Hello world 的客户端
*/
public class HelloWorldClient {
private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());
private final ManagedChannel channel;
private final GreeterGrpc.GreeterBlockingStub blockingStub;
/** 连接服务端的构造器 */
public HelloWorldClient(String host, int port) {
this(ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build());
}
/** 初始化通道 */
HelloWorldClient(ManagedChannel channel) {
this.channel = channel;
blockingStub = GreeterGrpc.newBlockingStub(channel);
}
// 关闭通道
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
/** 客户端请求 */
public void greet(String name) {
logger.info("Will try to greet " + 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("Greeting: " + response.getMessage());
}
public static void main(String[] args) throws Exception {
HelloWorldClient client = new HelloWorldClient("localhost", 50051);
try {
String user = "world";
if (args.length > 0) {
user = args[0];
}
client.greet(user);
} finally {
client.shutdown();
}
}
}
四 测试
1 启动服务端
2 启动客户端
3 服务端打印
信息: Server started, listening on 50051
4 客户端打印
六月 04, 2022 7:49:19 上午 io.grpc.examples.helloworld.HelloWorldClient greet
信息: Will try to greet world ...
六月 04, 2022 7:49:20 上午 io.grpc.examples.helloworld.HelloWorldClient greet
信息: Greeting: Hello world