背景:由于项目要对接到grcp 的框架,然后需要对接老外的东西,还有签名和证书刚开始没有接触其实有点懵逼。
gRPC 是由 Google 开发的高性能、开源的远程过程调用(RPC)框架。它建立在 HTTP/2 协议之上,使用 Protocol Buffers 作为其接口定义语言(IDL)。gRPC 被设计为可跨多种环境(包括客户端、服务器和各种语言)使用,支持多种编程语言,如 C、C++、Java、Go、Python、Ruby、Node.js 等。
gRPC 具有以下特点:
-
性能高效:gRPC 使用基于 HTTP/2 的传输协议,能够复用连接、多路复用请求、支持头部压缩等特性,从而提高了性能。
-
跨语言支持:gRPC 支持多种编程语言,使得客户端和服务器可以使用不同的编程语言实现,并且它们之间的通信依然高效。
-
IDL 和自动代码生成:gRPC 使用 Protocol Buffers 作为接口定义语言(IDL),定义服务接口和消息格式,并提供了自动生成客户端和服务器代码的工具。
-
多种调用方式:gRPC 支持四种调用方式,包括简单 RPC、服务器流式 RPC、客户端流式 RPC 和双向流式 RPC,可以根据业务需求选择合适的调用方式。
-
安全性:gRPC 支持 TLS/SSL 加密传输,保障通信的安全性。
-
插件机制:gRPC 提供了插件机制,可以扩展其功能,例如添加认证、日志、监控等功能。
总的来说,gRPC 是一个强大的远程过程调用框架,适用于构建分布式系统中的各种服务,并且在性能、跨语言支持和安全性方面具有很多优势。
一,开发工具集成:
安装指定插件,网上说还要Protobuf buffer 安装,但是我用的idea2018的版本搜索不到,这个不是必须的,可以不用。
二 protobuf编译器一定要安装配置一个: Releases · protocolbuffers/protobuf · GitHub
三,安装好插件后就可以看的了这俩个就是生产java代码的。
四,grpc 的文件格式:
syntax = "proto3";
package c3_vanilla_app;
option java_package = "com.test.conncar.c3vanillaapp";
option java_outer_classname = "C3VanillaAppProtos";
import "google/protobuf/empty.proto";
message ExampleRequestMessage {
string id = 1;
int64 timestamp = 2;
string message = 3;
}
message ExampleResponseMessage {
string message = 1;
}
service ExampleService {
rpc PostExampleMessages(ExampleRequestMessage) returns (ExampleResponseMessage) {}
}
生成出来的代码就是:
可以用命令生成,然后也可以用maven自动生成
pom加上这个插件就可以生产代码了:
<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>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
完整的pom文件:
<properties>
<protoc.version>3.25.2</protoc.version>
<grpc.version>1.61.1</grpc.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.25.2</version> <!-- 或者与你的 protoc.version 相匹配的版本 -->
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
</dependency>
</dependencies>
<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:${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>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jfrog.buildinfo</groupId>
<artifactId>artifactory-maven-plugin</artifactId>
<version>3.3.0</version>
<inherited>false</inherited>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>publish</goal>
</goals>
<configuration>
<artifactory>
<includeEnvVars>false</includeEnvVars>
<timeoutSec>60</timeoutSec>
<propertiesFile>publish.properties</propertiesFile>
</artifactory>
<publisher>
<contextUrl>${env.ARTIFACTORY_HOST_POM}</contextUrl>
<username>${env.ARTIFACTORY_CCAR_USER}</username>
<password>${env.ARTIFACTORY_CCAR_APIKEY}</password>
<excludePatterns>*-tests.jar</excludePatterns>
<repoKey>${CI_PROJECT_NAMESPACE}</repoKey>
<snapshotRepoKey>${CI_PROJECT_NAMESPACE}</snapshotRepoKey>
</publisher>
<buildInfo>
<buildName>${CI_PROJECT_NAME}</buildName>
<buildNumber>${CI_PIPELINE_ID}</buildNumber>
<buildUrl>${CI_PROJECT_URL}</buildUrl>
</buildInfo>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
生成的代码路径:
生成的代码,记得install的时候注释掉插件,然后进行install
然后本地写个client和sever就行了:
server:
package com.grpc.mistra.server;
import com.grpc.mistra.generate.MistraRequest;
import com.grpc.mistra.generate.MistraResponse;
import com.grpc.mistra.generate.MistraServiceGrpc;
import io.grpc.BindableService;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
/**
* Time: 14:46
* Description:
*/
public class MistraServer {
private int port = 8001;
private Server server;
private void start() throws IOException {
server = ServerBuilder.forPort(port)
.addService((BindableService) new MistraHelloWorldImpl())
.build()
.start();
System.out.println("------------------- 服务端服务已开启,等待客户端访问 -------------------");
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.err.println("*** shutting down gRPC server since JVM is shutting down");
MistraServer.this.stop();
System.err.println("*** server shut down");
}
});
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
final MistraServer server = new MistraServer();
//启动服务
server.start();
//服务一直在线,不关闭
server.blockUntilShutdown();
}
// 定义一个实现服务接口的类
private class MistraHelloWorldImpl extends MistraServiceGrpc.MistraServiceImplBase {
@Override
public void sayHello(MistraRequest mistraRequest, StreamObserver<MistraResponse> responseObserver) {
// 具体其他丰富的业务实现代码
System.err.println("server:" + mistraRequest.getName());
MistraResponse reply = MistraResponse.newBuilder().setMessage(("响应信息: " + mistraRequest.getName())).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
}
client:
package com.grpc.mistra.client;
import com.grpc.mistra.generate.MistraRequest;
import com.grpc.mistra.generate.MistraResponse;
import com.grpc.mistra.generate.MistraServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import java.util.concurrent.TimeUnit;
/**
* Time: 14:46
* Description:
*/
public class MistraClient {
private final ManagedChannel channel;
private final MistraServiceGrpc.MistraServiceBlockingStub blockingStub;
public MistraClient(String host, int port) {
channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext(true)
.build();
blockingStub = MistraServiceGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public void greet(String name) {
MistraRequest request = MistraRequest.newBuilder().setName(name).build();
MistraResponse response = blockingStub.sayHello(request);
System.out.println(response.getMessage());
}
public static void main(String[] args) throws InterruptedException {
MistraClient client = new MistraClient("127.0.0.1", 8001);
System.out.println("-------------------客户端开始访问请求-------------------");
for (int i = 0; i < 10; i++) {
client.greet("你若想生存,绝处也能缝生: " + i);
}
}
}
效果图:
grpc的调用类:
package com.grpc.mistra.generate;
import static io.grpc.MethodDescriptor.generateFullMethodName;
import static io.grpc.stub.ClientCalls.asyncUnaryCall;
import static io.grpc.stub.ClientCalls.blockingUnaryCall;
import static io.grpc.stub.ClientCalls.futureUnaryCall;
import static io.grpc.stub.ServerCalls.asyncUnaryCall;
import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
/**
* <pre>
* 声明一个服务名称
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler (version 1.11.0)",
comments = "Source: helloworld.proto")
public final class MistraServiceGrpc {
private MistraServiceGrpc() {
}
public static final String SERVICE_NAME = "mistra.MistraService";
// Static method descriptors that strictly reflect the proto.
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
@Deprecated // Use {@link #getSayHelloMethod()} instead.
public static final io.grpc.MethodDescriptor<MistraRequest,
MistraResponse> METHOD_SAY_HELLO = getSayHelloMethodHelper();
private static volatile io.grpc.MethodDescriptor<MistraRequest,
MistraResponse> getSayHelloMethod;
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
public static io.grpc.MethodDescriptor<MistraRequest,
MistraResponse> getSayHelloMethod() {
return getSayHelloMethodHelper();
}
private static io.grpc.MethodDescriptor<MistraRequest,
MistraResponse> getSayHelloMethodHelper() {
io.grpc.MethodDescriptor<MistraRequest, MistraResponse> getSayHelloMethod;
if ((getSayHelloMethod = MistraServiceGrpc.getSayHelloMethod) == null) {
synchronized (MistraServiceGrpc.class) {
if ((getSayHelloMethod = MistraServiceGrpc.getSayHelloMethod) == null) {
MistraServiceGrpc.getSayHelloMethod = getSayHelloMethod =
io.grpc.MethodDescriptor.<MistraRequest, MistraResponse>newBuilder()
.setType(io.grpc.MethodDescriptor.MethodType.UNARY)
.setFullMethodName(generateFullMethodName(
"mistra.MistraService", "SayHello"))
.setSampledToLocalTracing(true)
.setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
MistraRequest.getDefaultInstance()))
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
MistraResponse.getDefaultInstance()))
.setSchemaDescriptor(new MistraServiceMethodDescriptorSupplier("SayHello"))
.build();
}
}
}
return getSayHelloMethod;
}
/**
* Creates a new async stub that supports all call types for the service
*/
public static MistraServiceStub newStub(io.grpc.Channel channel) {
return new MistraServiceStub(channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
public static MistraServiceBlockingStub newBlockingStub(
io.grpc.Channel channel) {
return new MistraServiceBlockingStub(channel);
}
/**
* Creates a new ListenableFuture-style stub that supports unary calls on the service
*/
public static MistraServiceFutureStub newFutureStub(
io.grpc.Channel channel) {
return new MistraServiceFutureStub(channel);
}
/**
* <pre>
* 声明一个服务名称
* </pre>
*/
public static abstract class MistraServiceImplBase implements io.grpc.BindableService {
/**
* <pre>
* 请求参数MistraRequest 响应参数MistraResponse
* </pre>
*/
public void sayHello(MistraRequest request,
io.grpc.stub.StreamObserver<MistraResponse> responseObserver) {
asyncUnimplementedUnaryCall(getSayHelloMethodHelper(), responseObserver);
}
@Override
public final io.grpc.ServerServiceDefinition bindService() {
return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
.addMethod(
getSayHelloMethodHelper(),
asyncUnaryCall(
new MethodHandlers<
MistraRequest,
MistraResponse>(
this, METHODID_SAY_HELLO)))
.build();
}
}
/**
* <pre>
* 声明一个服务名称
* </pre>
*/
public static final class MistraServiceStub extends io.grpc.stub.AbstractStub<MistraServiceStub> {
private MistraServiceStub(io.grpc.Channel channel) {
super(channel);
}
private MistraServiceStub(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@Override
protected MistraServiceStub build(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
return new MistraServiceStub(channel, callOptions);
}
/**
* <pre>
* 请求参数MistraRequest 响应参数MistraResponse
* </pre>
*/
public void sayHello(MistraRequest request,
io.grpc.stub.StreamObserver<MistraResponse> responseObserver) {
asyncUnaryCall(
getChannel().newCall(getSayHelloMethodHelper(), getCallOptions()), request, responseObserver);
}
}
/**
* <pre>
* 声明一个服务名称
* </pre>
*/
public static final class MistraServiceBlockingStub extends io.grpc.stub.AbstractStub<MistraServiceBlockingStub> {
private MistraServiceBlockingStub(io.grpc.Channel channel) {
super(channel);
}
private MistraServiceBlockingStub(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@Override
protected MistraServiceBlockingStub build(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
return new MistraServiceBlockingStub(channel, callOptions);
}
/**
* <pre>
* 请求参数MistraRequest 响应参数MistraResponse
* </pre>
*/
public MistraResponse sayHello(MistraRequest request) {
return blockingUnaryCall(
getChannel(), getSayHelloMethodHelper(), getCallOptions(), request);
}
}
/**
* <pre>
* 声明一个服务名称
* </pre>
*/
public static final class MistraServiceFutureStub extends io.grpc.stub.AbstractStub<MistraServiceFutureStub> {
private MistraServiceFutureStub(io.grpc.Channel channel) {
super(channel);
}
private MistraServiceFutureStub(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@Override
protected MistraServiceFutureStub build(io.grpc.Channel channel,
io.grpc.CallOptions callOptions) {
return new MistraServiceFutureStub(channel, callOptions);
}
/**
* <pre>
* 请求参数MistraRequest 响应参数MistraResponse
* </pre>
*/
public com.google.common.util.concurrent.ListenableFuture<MistraResponse> sayHello(
MistraRequest request) {
return futureUnaryCall(
getChannel().newCall(getSayHelloMethodHelper(), getCallOptions()), request);
}
}
private static final int METHODID_SAY_HELLO = 0;
private static final class MethodHandlers<Req, Resp> implements
io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
private final MistraServiceImplBase serviceImpl;
private final int methodId;
MethodHandlers(MistraServiceImplBase serviceImpl, int methodId) {
this.serviceImpl = serviceImpl;
this.methodId = methodId;
}
@Override
@SuppressWarnings("unchecked")
public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
switch (methodId) {
case METHODID_SAY_HELLO:
serviceImpl.sayHello((MistraRequest) request,
(io.grpc.stub.StreamObserver<MistraResponse>) responseObserver);
break;
default:
throw new AssertionError();
}
}
@Override
@SuppressWarnings("unchecked")
public io.grpc.stub.StreamObserver<Req> invoke(
io.grpc.stub.StreamObserver<Resp> responseObserver) {
switch (methodId) {
default:
throw new AssertionError();
}
}
}
private static abstract class MistraServiceBaseDescriptorSupplier
implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
MistraServiceBaseDescriptorSupplier() {
}
@Override
public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
return MistraProto.getDescriptor();
}
@Override
public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
return getFileDescriptor().findServiceByName("MistraService");
}
}
private static final class MistraServiceFileDescriptorSupplier
extends MistraServiceBaseDescriptorSupplier {
MistraServiceFileDescriptorSupplier() {
}
}
private static final class MistraServiceMethodDescriptorSupplier
extends MistraServiceBaseDescriptorSupplier
implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
private final String methodName;
MistraServiceMethodDescriptorSupplier(String methodName) {
this.methodName = methodName;
}
@Override
public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
return getServiceDescriptor().findMethodByName(methodName);
}
}
private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
public static io.grpc.ServiceDescriptor getServiceDescriptor() {
io.grpc.ServiceDescriptor result = serviceDescriptor;
if (result == null) {
synchronized (MistraServiceGrpc.class) {
result = serviceDescriptor;
if (result == null) {
serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
.setSchemaDescriptor(new MistraServiceFileDescriptorSupplier())
.addMethod(getSayHelloMethodHelper())
.build();
}
}
}
return result;
}
}
咋们就完成了grpc接入到java里面调用了本质上其实代码没有区别,小杨看了一下,他就是多了一些设计模式生产的代码,工厂构建等。
————没有与生俱来的天赋,都是后天的努力拼搏(我是小杨,谢谢你的关注和支持)