gRPC框架学习:6、Java+gRPC+maven+idea实例测试并打jar包
1. 前言
之前总结过go的使用实例,目前遇到项目部分功能sdk提供了Java版本的SDK,因此该模块暂时使用Java来开发使用,所以这里总结一下该基于Java的进程模块如何使用gRPC接口并通过maven+idea工件的方式将该模块和依赖gRPC的jar包打包成统一的jar包,之后通过Jdk执行jar包运行,可以做到在具备jdk的环境下跨平台运行。
2. pom.xml文件及生成包含gRPC接口的target(注意匹配jdk版本)
官方给的Java的快速gRPC实例是使用的gradlew方式:https://grpc.io/docs/languages/java/quickstart/,所以如果可以的话项目最好以gradlew方式构建,目前维护的项目使用的maven,所以在GitHub上找一下maven方式:https://github.com/grpc/grpc-java
以下是GitHub上目前给到的pom.xml的内容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.35.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.35.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.35.0</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
</dependencies>
<groupId>org.example</groupId>
<artifactId>test-grpc</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.19.2:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.44.1:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
这个上面提到可能需要jdk9,否则很可能编译不过,会出现找不到符号等问题。
下面这个是我目前尝试jdk8可以使用的pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>test-grpc</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>1.11.0</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.1.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.0.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3. proto文件
示例的protobuf可以参考grpc-Java中的示例代码:
// Copyright 2015 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
然后我们照着写一个获取版本号的:
syntax = "proto3";
option java_package = "io.grpc.examples.test";
option java_outer_classname = "TestProto";
service TestGRPC {
rpc GetVersion (GetVersionRequest) returns (GetVersionResponse);
}
message BaseResponse {
int32 code = 1; // 错误码 0:成功; 其他:参考《错误码统计》
string message = 2; // 错误消息
}
/*
** 版本信息
*/
message Version {
string software_version = 1; // 软件版本号
int64 last_compile_time = 2; // 上次编译时间
}
message GetVersionRequest {
}
message GetVersionResponse {
BaseResponse response = 1;
Version version = 2;
}
4. 生成gRPC接口
第一次的话同步就会生成对应的target文件夹,里面包含gRPC相关的接口,后续有修改也可以通过clean、compile等方式进行同步(目前我的idea是2021.1的,不同版本可能会有差异)。
5. 使用gRPC接口的Java客户端和服务端示例
服务端示例代码:
import java.io.IOException;
import io.grpc.Server;
import io.grpc.ServerBuilder;
public class GRpcServer {
private Server server;
public static void main(String[] args) {
final GRpcServer server = new GRpcServer();
try {
server.start();
} catch (IOException e) {
e.printStackTrace();
}
try {
server.blockUntilShutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void start() throws IOException {
int port = 800;
server = ServerBuilder.forPort(port)
.addService(new TestGrpcApi())
.build()
.start();
System.out.println("grpc server start!");
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
}
import io.grpc.examples.test.*;
import io.grpc.stub.StreamObserver;
class TestGrpcApi extends TestGRPCGrpc.TestGRPCImplBase {
@Override
public void getVersion(TestProto.GetVersionRequest request, StreamObserver<TestProto.GetVersionResponse> responseObserver) {
System.out.println("请求信息" + request);
TestProto.GetVersionResponse reply = TestProto.GetVersionResponse.newBuilder()
.setResponse(
TestProto.BaseResponse.newBuilder()
.setMessage("success").setCode(0))
.setVersion(
TestProto.Version.newBuilder()
.setSoftwareVersion("1.0.0")
.setLastCompileTime(System.currentTimeMillis()))
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
System.out.println("发送版本信息完成!");
}
}
客户端示例代码:
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.examples.test.TestGRPCGrpc;
import io.grpc.examples.test.TestProto;
public class GRpcClient {
private final ManagedChannel channel;
private final TestGRPCGrpc.TestGRPCBlockingStub blockingStub;
static GRpcClient client;
public static void main(String[] args) {
client = new GRpcClient("127.0.0.1", 800);
client.GetVersion();
}
public GRpcClient(String host, int port) {
channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build();
blockingStub = TestGRPCGrpc.newBlockingStub(channel);
}
private void GetVersion() {
TestProto.GetVersionRequest request = TestProto.GetVersionRequest.newBuilder().build();
TestProto.GetVersionResponse response;
response = blockingStub.getVersion(request);
System.out.println("get grpc server resp:" + response.getResponse());
System.out.println("get grpc server ver:" + response.getVersion());
}
}
结果:
6. 使用idea构建工件方式打包成jar包运行
之后我们将该获取版本的gRPC服务主程序打包成jar包,然后方便运行在不同的设备上,这里我们既可以采用idea自带的构建工件方式,也可以使用maven自带的打包为一个jar包的方式,这里由于历史遗留原因暂时只说明idea打工件方式,maven方式自行摸索一下即可。
创建一个工件(不清楚idea工件打包的可以看一下这里:https://blog.csdn.net/weixin_39510813/article/details/117262061):
之后构建->构建工件->构建出jar包即可。
这里以server打包jar包运行,然后发送客户端请求作为测试:
7. 最后
需要注意的点就是Jdk版本匹配的问题,否则编译grpc的接口时可能会报无符号等错误,这个错误不一定是maven缺少部分依赖的原因,也可能是你使用的grpc的依赖需要的jdk版本有差异。
|