背景:由于项目要对接到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() {@Overridepublic 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 {@Overridepublic 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);}@Overridepublic 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);}@Overrideprotected 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);}@Overrideprotected 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);}@Overrideprotected 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> implementsio.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 MistraServiceBaseDescriptorSupplierimplements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {MistraServiceBaseDescriptorSupplier() {}@Overridepublic com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {return MistraProto.getDescriptor();}@Overridepublic com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {return getFileDescriptor().findServiceByName("MistraService");}}private static final class MistraServiceFileDescriptorSupplierextends MistraServiceBaseDescriptorSupplier {MistraServiceFileDescriptorSupplier() {}}private static final class MistraServiceMethodDescriptorSupplierextends MistraServiceBaseDescriptorSupplierimplements io.grpc.protobuf.ProtoMethodDescriptorSupplier {private final String methodName;MistraServiceMethodDescriptorSupplier(String methodName) {this.methodName = methodName;}@Overridepublic 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里面调用了本质上其实代码没有区别,小杨看了一下,他就是多了一些设计模式生产的代码,工厂构建等。
————没有与生俱来的天赋,都是后天的努力拼搏(我是小杨,谢谢你的关注和支持)