前言
Dubbo2.7.5版本开始支持gRPC协议,Dubbo底层还是依赖于io.grpc,如果你要去看Dubbo关于grpc协议的源码,那么首先需要了解io.grpc,本文通过一个简单的示例,用Java启动一个gRPC的服务,并用Postman发起gRPC调用。
项目配置
新建一个Maven项目,首先导入依赖,这里简单粗暴直接导入all。
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>1.56.1</version>
</dependency>
</dependencies>
gRPC 使用 Protocol Buffers(简称 proto)文件来定义服务。proto 文件定义了可以通过 gRPC 进行通信的消息格式和服务接口。proto 文件使用一种简洁且可扩展的语法来描述这些消息和接口,并且可以根据需要生成不同语言的代码。
因为我们用的是Java语言,所以需要依赖三方库来帮我们将proto文件生成Java对应的代码。
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
属性配置如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<protoc.version>3.12.0</protoc.version>
<grpc.version>1.56.1</grpc.version>
</properties>
定义服务
gRPC通过proto文件来定义服务,这里给出一个简单示例:HelloService服务有一个say方法。
syntax = "proto3";
option java_multiple_files = true;
option java_package = "org.example.service";
option java_outer_classname = "HelloServiceProto";
option objc_class_prefix = "HLW";
// The greeting service definition.
service HelloService {
// Sends a greeting
rpc say (RequestData) returns (ResponseData) {}
}
// The request message containing the user's name.
message RequestData {
string name = 1;
}
// The response message containing the greetings
message ResponseData {
string message = 1;
}
然后分别通过mvn protobuf:compile和mvn protobuf:compile-custom命令生成对应的bean和service。
实现服务
我们在HelloService.proto文件中定义了我们的服务,然后执行命令生成对应的Java类,接下来需要实现服务逻辑。
新建一个类继承HelloServiceGrpc.HelloServiceImplBase,重写方法即可。
注意:
HelloServiceGrpc是插件自动生成的类!!!
public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
@Override
public void say(RequestData request, StreamObserver<ResponseData> responseObserver) {
System.err.println(request.getName());
responseObserver.onNext(ResponseData.newBuilder().setMessage("你要返回的数据").build());
responseObserver.onCompleted();
}
}
服务启动
通过ServerBuilder构建一个Server实例,将我们的服务实现加入进去,启动即可。
Server server = ServerBuilder
.forPort(port)
.addService(new HelloServiceImpl())
.build()
.start();
服务调用
篇幅原因就不写代码去调用服务了,Postman是支持直接调用gRPC服务的。
首先输入服务IP和端口,我本地是127.0.0.1:9001,然后导入proto文件,让Postman知道有哪些服务方法,这里只有一个方法:say。
尾巴
gRPC基于HTTP2协议,借助HTTP2的分帧消息机制,实现了高效的数据传输。底层gRPC使用Netty作为数据传输的工具,确保了性能和可靠性。感兴趣的同学可以去看看gRPC的源码,看看它是怎么处理HTTP2的Frame消息的。