grpc java 文档中文版,gRPC之java语言的简单Demo

最近由于项目需要,就简单看了下gRPC入门,使用起来挺简单的。这里就顺便记录一下,便于后面回顾。

RPC是什么

说到RPC(Remote Process Communication,远程过程调用)就不得不说到进程间通信(Inter-process Communication,简称IPC),IPC是指多个进程之间传送数据或信号的一些技术或方法。

而IPC又分为本地过程调用(LPC)和远程过程调用(RPC),这两者的区别就是 LPC的调用可以共享内存空间,比较方便;而RPC的调用双方则不在同一个主机中,无法像LPC那样方便。

说到底,RPC就是在本地来 调用远程的方法。而RPC框架要做的就是 让远程调用 像本地调用一样方便,而这个调用过程则是RPC框架需要做的工作。这个工作涉及到大概 两个方面:序列化协议 和 传输协议。

1、常见的序列化协议有:

基于文本(text)的:XML、JSON

基于二进制(binary)的: Protocol Buffer、Thrift等

2、常见的传输协议有:

传输层的: TCP(基于Socket)、UDP

应用层的:HTTP1.1、HTTP2.0

而RPC框架中,通常使用的序列化协议包括Protocol Buffer、Thrift等,传输协议则常用TCP、HTTP2.0等。

更多的内容可以参考博客:【RPC简介及框架选择】

gRPC框架

上面简单介绍了RPC机制的作用,现如今已经出现了许多优秀的RPC框架,比如:gRPC、Dubbo、Thrift等。这些框架在 序列化协议和传输协议两部分都有不同的选择,各有优劣。不过,没必要全部都去学习一遍,可以简单尝试一种,大概了解运行机制即可。

下面是以gRPC的简单使用为例,了解gRPC的运行过程和用法。

gRPC使用的序列化协议是 Protocol Buffer,使用的传输协议是 HTTP2.0协议。

具体步骤如下:

1、创建一个maven项目,创建src/main/proto目录,在其中添加定义好的远程API接口hello.proto文件,如下:

// 使用该proto文件可以定义交互的服务接口,基于该文件编译成的源文件可以分别复制到 client端和server端,便于两者使用

syntax = "proto3"; // 定义语法类型

package hello; // 定义作用域

option java_multiple_files = false; // 表示下面的message不需要编译成多个java文件

option java_outer_classname = "HelloMessage"; // 表示下面的message编译成的java类文件的名字

option java_package = "grpc"; //指定该proto文件编译成的java源文件的包名

service Hello { // 定义服务

rpc sayHello(HelloRequest) returns(HelloResponse) {}

}

message HelloRequest { // 定义请求的消息体

string name = 1;

}

message HelloResponse { // 定义回复的消息体

string message = 1;

}

2、在pom.xml文件中添加gRPC依赖与插件,参考grpc-java仓库,如下:

依赖为:

io.grpc

grpc-netty-shaded

1.31.1

io.grpc

grpc-protobuf

1.31.1

io.grpc

grpc-stub

1.31.1

org.apache.tomcat

annotations-api

6.0.53

provided

插件为:

kr.motd.maven

os-maven-plugin

1.6.2

org.xolstice.maven.plugins

protobuf-maven-plugin

0.6.1

com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}

grpc-java

io.grpc:protoc-gen-grpc-java:1.31.1:exe:${os.detected.classifier}

compile

compile-custom

org.apache.maven.plugins

maven-compiler-plugin

3.1

1.8

1.8

utf-8

3、执行mvn clean compile命令,然后在生成的target/generated-sources/ptotobuf文件夹中找到服务接口对应的类文件 和 接口参数/返回值对应的类文件。

将这两个文件分别复制到client端 和 server端的java源文件中。

4、编写server端代码,如下:

public class ServerDemo {

// 定义一个Server对象,监听端口来获取rpc请求,以进行下面的处理

private Server server;

//使用main方法来测试server端

public static void main(String[] args) throws IOException, InterruptedException {

final ServerDemo serverDemo = new ServerDemo();

//启动server

serverDemo.start();

//block 一直到退出程序

serverDemo.blockUntilShutdown();

}

/**

* 启动一个Server实例,监听client端的请求并处理

* @throws IOException

*/

private void start() throws IOException {

//server运行在的端口号

int port = 50051;

// 给server添加监听端口号,添加 包含业务处理逻辑的类,然后启动

server = ServerBuilder.forPort(port)

.addService(new HelloImpl())

.build()

.start();

}

/**

* 阻塞server直到关闭程序

* @throws InterruptedException

*/

private void blockUntilShutdown() throws InterruptedException {

if (server != null) {

server.awaitTermination();

}

}

/**

* proto文件被编译后,在生成的HelloGrpc的抽象内部类HelloImplBase中包含了 proto中定义的服务接口的简单实现

* 该HelloImpl类需要重写这些方法,添加需要的处理逻辑

*/

static class HelloImpl extends HelloGrpc.HelloImplBase {

// proto文件中的sayHello服务接口被编译后,在生成的HelloGrpc的抽象内部类HelloImplBase中有一个简单的实现

// 因此,在server端需要重写这个方法,添加上相应的逻辑

@Override

public void sayHello(HelloMessage.HelloRequest req, StreamObserver responseObserver) {

HelloMessage.HelloResponse reply = HelloMessage.HelloResponse.newBuilder().setMessage("(server端的sayHello()方法处理结果) Hello," + req.getName()).build();

// 调用onNext()方法来通知gRPC框架把reply 从server端 发送回 client端

responseObserver.onNext(reply);

// 表示完成调用

responseObserver.onCompleted();

}

}

}

5、编写client端代码,如下:

public class ClientDemo {

//使用main方法来测试client端

public static void main(String[] args) throws Exception {

ClientDemo clientDemo = new ClientDemo();

try {

//基于gRPC远程调用对应的方法

clientDemo.remoteCall("【zhongyuan】");

} finally {

}

}

/**

* 基于gRPC框架的使用步骤,进行远程调用

* @param name

*/

public void remoteCall(String name) {

HelloMessage.HelloRequest request = HelloMessage.HelloRequest.newBuilder().setName(name).build();

HelloMessage.HelloResponse response;

try {

// 基于访问地址 创建通道

Channel channel = ManagedChannelBuilder.forAddress("localhost", 50051).usePlaintext().build();

// 利用通道 创建一个桩(Stub)对象

HelloGrpc.HelloBlockingStub blockingStub = HelloGrpc.newBlockingStub(channel);

//通过桩对象来调用远程方法

response = blockingStub.sayHello(request);

} catch (StatusRuntimeException e) {

return;

}

System.out.println("client端远程调用sayHello()的结果为:\n\n" + response.getMessage());

}

}

6、接下来,先运行server端main()函数,再运行client端的main()函数,即可测试rpc远程调用结果,如下:

044764139cba2919edf208deee15630f.png

参考:

博客:

标签:调用,java,gRPC,Demo,server,grpc,RPC

来源: https://www.cnblogs.com/zhongyuanzhao000/p/13783165.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值