基本概念

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生成源代码

6c8841fa3a16296aab1612ab295aae6e.png

项目target下生成如下代码,实际项目上线后可以把该代码copy到对应src下面,把target下面的源码删除掉,这样也不用每次用maven中plugin去再生成代码。

24ba89688892cf8faa310a1db7b8d5d2.png

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/

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐