java grpc_gRPC的Java实现
基本概念gRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。在 gRPC 里,客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRP
基本概念
gRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。在 gRPC 里,客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。
gRPC具有以下特点:
(1)基于 HTTP/2, 继而提供了连接多路复用、Body 和 Header 压缩等机制。可以节省带宽、降低TCP链接次数、节省CPU使用和延长电池寿命等。
(2)支持主流开发语言(C, C++, Python, PHP, Ruby, NodeJS, C#, Objective-C、Golang、Java)
(3)IDL (Interface Definition Language) 层使用了 Protocol Buffers, 非常适合团队的接口设计
HelloWorld实例详解
gRPC的使用通常包括如下几个步骤:
通过protobuf来定义接口和数据类型
编写gRPC server端代码
编写gRPC client端代码
编写helloworld.proto
syntax= "proto3";
optionjava_multiple_files = true;
optionjava_package = "com.manong.helloworld";
optionjava_outer_classname = "HelloWorldProto";
optionobjc_class_prefix = "HLW";
packagehelloworld;// The greeting service definition.serviceGreeter {
// Sends a greetingrpcSayHello (HelloRequest) returns(HelloReply) {}
}
// The request message containing the user's name.messageHelloRequest {
stringname = 1;}
// The response message containing the greetingsmessageHelloReply {
stringmessage = 1;}
Maven配置
3.12.0
3.12.0
1.31.1
io.grpc
grpc-bom
1.31.1
pom
import
io.grpc
grpc-protobuf
io.grpc
grpc-stub
io.grpc
grpc-services
io.grpc
grpc-netty-shaded
runtime
kr.motd.maven
os-maven-plugin
1.6.2
org.xolstice.maven.plugins
protobuf-maven-plugin
0.6.1
com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
grpc-java
io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
compile
compile-custom
org.apache.maven.plugins
maven-enforcer-plugin
1.4.1
enforce
enforce
运行maven插件中下面命令,根据proto生成源代码
项目target下生成如下代码,实际项目上线后可以把该代码copy到对应src下面,把target下面的源码删除掉,这样也不用每次用maven中plugin去再生成代码。
Server端代码
importcom.manong.grpc.helloworld.GreeterGrpc;
importcom.manong.grpc.helloworld.HelloReply;
importcom.manong.grpc.helloworld.HelloRequest;
importio.grpc.Server;
importio.grpc.ServerBuilder;
importio.grpc.stub.StreamObserver;
importjava.io.IOException;
importjava.net.InetAddress;
importjava.util.Random;
importjava.util.concurrent.TimeUnit;
importjava.util.logging.Level;
importjava.util.logging.Logger;
public classHostnameServer extendsGreeterGrpc.GreeterImplBase {
private static finalLogger logger= Logger.getLogger(HostnameServer.class.getName());
private finalString serverName;
publicHostnameServer(String serverName) {
if(serverName == null) {
serverName = determineHostname();}
this.serverName= serverName;}
@Overridepublic voidsayHello(HelloRequest req,StreamObserver responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello , "+ req.getName() + ", from "+ serverName)
.build();responseObserver.onNext(reply);responseObserver.onCompleted();}
private staticString determineHostname() {
try{
returnInetAddress.getLocalHost().getHostName();} catch(IOException ex) {
logger.log(Level.INFO,"Failed to determine hostname. Will generate one",ex);}
// Strange. Well, let's make an identifier for ourselves.return"generated-"+ newRandom().nextInt();}
public voidinit() throwsException {
intport = 50051;String hostname = "0.0.0.0";
finalServer server = ServerBuilder.forPort(port)
.addService(this)
.build()
.start();System.out.println("Listening on port "+ port);Runtime.getRuntime().addShutdownHook(newThread() {
@Overridepublic voidrun() {
server.shutdown();
try{
if(!server.awaitTermination(30,TimeUnit.SECONDS)) {
server.shutdownNow();server.awaitTermination(5,TimeUnit.SECONDS);}
} catch(InterruptedException ex) {
server.shutdownNow();}
}
});server.awaitTermination();}
public static voidmain(String[] args) throwsException {
HostnameServer hostnameServer = newHostnameServer("grpc server");hostnameServer.init();}
}
运行Server,出现如下输出表示Server已经正常启动
Client端代码
importcom.manong.grpc.helloworld.GreeterGrpc;
importcom.manong.grpc.helloworld.HelloReply;
importcom.manong.grpc.helloworld.HelloRequest;
importio.grpc.ManagedChannel;
importio.grpc.ManagedChannelBuilder;
public classHostnameClient {
public static voidmain(String[] args) {
String target = "localhost:50051";ManagedChannel channel = ManagedChannelBuilder.forTarget(target).usePlaintext().build();
try{
GreeterGrpc.GreeterBlockingStub greeterBlockingStub = GreeterGrpc.newBlockingStub(channel);//传参HelloRequest defaultInstance = HelloRequest.newBuilder().setName("manong").build();HelloReply helloReply = greeterBlockingStub.sayHello(defaultInstance);System.out.println(helloReply.getMessage());} catch(Exception e) {
e.printStackTrace();}
}
}
运行client端代码,出现如下输出,表示调用server服务成功并获得返回值
到此为止,一个完整的基于Java的gRpc demo就完成了。想了解更多可以猛击https://grpc.io/
更多推荐
所有评论(0)