java 调用远程grpc_帮你节省一半时间的gRPC入门指南

写在前面

从上图和文档中我们可以了解到,用gRPC来进行远程服务调用就仅仅需要gRPC Stub(Client)用Proto Request向远方的gRPC Server发起服务调用,然后远方的gRPC Server通过Proto Response(s)将调用结果返回给gRPC Stub。

上面这段逻辑的背后,gRPC做了什么:

一个gRPC从开始发起请求到返回总共要经历过序列化,编解码,以及网络传输这些内容。这些东西在我们使用gRPC框架做远程服务调用的时候完全感知不到!

至于gRPC的stub之间的连接管理,健康检查,负载均衡,异常重试,优雅启停机,熔断限流等等是需要我们从gRPC源码中获得这些知识的!

从0写一个Java-gRPC项目

本demo项目代码:https://github.com/cld378632668/gRPC-java-introduction​github.com

首先编写.proto文件,其中会定义service和message,比如这里我们定义:

service user{

rpc login(LoginRequest) returns (APIResponse);

rpc logout(Empty) returns (APIResponse);

}

message LoginRequest{

string username = 1;

string passwd = 2;

}

message APIResponse{

string responsemessage = 1;

int32 responseCode = 2;

}

message Empty{

}

然后不同的语言有不同的工具根据.proto生成源代码文件(如.java,本文以JAVA来讲解)。

例如我们在定义了service HelloService,mesage HelloRequest,message HelloResponse,自动生成的文件有:

Hello.java

HelloRequest.java

HelloRequestOrBuilder.java

HelloResponse.java

HelloResponseOrBuilder.java

在不同的RPC版本中,上面五个类可能全都放在一个Hello.java文件中

GreetingService.java

生成RPC通信代码:

HelloServiceGrpc.java,在其他RPC版本中该文件的名字可能为helloGrpc.java

该文件中包含有类:

helloServiceImplBase

helloStub

helloBlockingStub

helloFutureStub

自定义Service类

接下来我们需要在自己创建的服务端项目中实现一个HelloService类,这个类继承helloServiceImplBase,然后重写login和logout两个方法,这两个方法在后面的客户端中可以通过stub.login(..)的形式被调用。

class HelloService extends HelloGrpc.HelloImplBase {

@Override

public void login(User.LoginRequest request, StreamObserver responseObserver) {

String username = request.getUsername();

String password = request.getPasswd();

User.APIResponse.Builder response = User.APIResponse.newBuilder();

// APIResponse对应.proto里对应的一个message的名字

if (username.equals(password)){

response.setResponseCode(0).setResponsemessage("SUCCESS");

}else{

response.setResponseCode(100).setResponsemessage("INVALID PASSWD");

}

responseObserver.onNext(response.build());

responseObserver.onCompleted();

}

}

自定义服务端

一共三行核心代码。

// 服务的添加:

io.grpc.Server server = ServerBuilder.forPort(9090).addService(new 自定义的Service类名1()).

.addService(new Service2()).addService(new Service3()).build();

// 服务的启动:

server.start();

// 服务的关闭:

server.awaitTermination();

自定义客户端

自定义的客户端通过stub调用服务端的方法,服务端的方法一开始是定义在.proto的service中的,如rpc login(LoginRequest) returns (APIResponse); LoginRequest和APIResponse被定义为两个message.

标准的grpc client调用代码,最简单的方式,就三行代码:

ManagedChannelImpl channel = NettyChannelBuilder.forAddress("127.0.0.1", 6556).build();

// 其他写法1:

// ManagedChannelImpl channel = ManagedChannelBuilder.forAddress(host, port)

.usePlaintext()

.build();

DemoServiceGrpc.DemoServiceBlockingStub stub = DemoServiceGrpc.newBlockingStub(channel);

stub.login(LoginRequest.getDefaultInstance());

这三行代码,完成了grpc客户端调用服务器端最重要的三个步骤:创建连接到远程服务器的 channel

构建使用该channel的客户端stub

通过stub调用服务方法,执行RPC调用

代码参考

完整的代码构建过程可以参考:

1、微信文章.孟君的编程札记.一步步完成gRPC示例。

2、youtube教程:https://www.youtube.com/watch?v=JFzAe9SvNaU&list=PLI5t0u6ye3FGXJMh5kU2RvN0xrul67p7R​www.youtube.com

Go Generated Code Reference

Thread-safety: note that client-side RPC invocations and server-side RPC handlersare thread-safeand are meant to be run on concurrent goroutines. But also note that forindividual streams, incoming and outgoing data is bi-directional but serial; so e.g.individual streamsdo not supportconcurrent readsorconcurrent writes(but reads are safely concurrentwithwrites).

推荐资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值