背景

rpc就是Remote Procedure Call的简称,翻译成中文就是远程过程调用。在很多的大型系统中,比如java体系的项目中,如果需要调用数据分析能力或者调用底层的dll代码包,就显得有点捉襟见肘的,此时如果有一个提供rpc服务的中间件就可以很好的解决这个问题,让java体系可以拥有这种能力,只需要简单通信就可以了。在项目中,我通过google的protobuf的序列化手段,基于http协议实现了grpc,让java体系可以调用python中间件提供的能力。

参考资料

https://www.zhihu.com/question/41609070/answer/1030913797 既然有 HTTP 请求,为什么还要用 RPC 调用? - 易哥的回答 - 知乎
https://zhuanlan.zhihu.com/p/36427583 如何给老婆解释什么是RPC - 柳树的文章 - 知乎
https://www.grpc.io/ grpc官网
https://developers.google.com/protocol-buffers protobuf官网

应用案例

gRPC 是一种现代开源高性能远程过程调用 (RPC) 框架,可以在任何环境中运行。它可以通过对负载平衡、跟踪、健康检查和身份验证的可插拔支持,有效地连接数据中心内和数据中心之间的服务。它还适用于分布式计算的最后一英里,将设备、移动应用程序和浏览器连接到后端服务。特性如下:
1.简单的服务定义
使用 Protocol Buffers 定义您的服务,这是一种强大的二进制序列化工具集和语言。
2.快速启动并扩展
使用一行代码安装运行时和开发环境,并使用框架扩展到每秒数百万次 RPC。
3.跨语言和平台工作
以各种语言和平台为您的服务自动生成惯用的客户端和服务器存根。
4.双向流和集成身份验证
双向流和完全集成的可插拔身份验证与基于 HTTP/2 的传输。
grpc与protobuf是相辅相成的,想要使用grpc,必须先学会使用protobuf,grpc跨语言和平台工作的能力是protobuf赋予的。但是利用传统的protobuf的生成器,反而不能生成grpc的代码,java语言有专门的grpc的代码生成的maven插件。接下来的内容,是假设你会protobuf的,如果不会的话,去参考资料里面学一下protobuf。

1.定义proto文件

在proto文件中定义了有哪些对外接口,以及这个方法的入参和回参。这里贴上我项目中到的例子,使用python调用yolo模型,实现目标检测。定义了三个方法,以及方法中使用到的参数,包括入参和回参。

 syntax = "proto3";option java_multiple_files = false; //不要拆分成多个文件
option java_package = "com.rpc.yolo";
option java_outer_classname = "YoloProto";// yolo模型对外提供的接口
service YoloFun {// 初始化rpc init (InitRequest) returns (InitReply) {}// 检测rpc detection (DetectionRequest) returns (DetectionReply) {}// 模拟方法rpc free (FreeRequest) returns (FreeReply) {}
}// 初始化方法发送对象
message InitRequest {string id = 1;string cfg = 2;string data = 3;string weights= 4;
}
// 初始化方法反馈对象
message InitReply {string result = 1;
}// 检测方法发送对象
message DetectionRequest {string id = 1; //模型编号string path = 2; //原图的文件路径 /usr/img/1.jpgstring detect_file_path = 3; //识别后的文件路径 /usr/local/1.jpg
}
//怕掉精度,直接存string
message Box{string x = 1;string y = 2;string w = 3;string h = 4;string obj = 5;string prob = 6;
}
// 检测方法反馈对象
message DetectionReply {string msg = 1;repeated Box boxes = 2;
}// 释放方法发送对象
message FreeRequest {string id = 1;
}
// 释放方法反馈对象
message FreeReply {string result = 1;
}

2.利用maven插件生成基础代码

定义好了proto文件之后,需要生成proto文件对应的java代码,方便上层应用调用。生成代码的过程,需要使用maven的插件,如下:

    <properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>io.grpc</groupId><artifactId>grpc-netty-shaded</artifactId><version>1.39.0</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-protobuf</artifactId><version>1.39.0</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-stub</artifactId><version>1.39.0</version></dependency><dependency> <!-- necessary for Java 9+ --><groupId>org.apache.tomcat</groupId><artifactId>annotations-api</artifactId><version>6.0.53</version><scope>provided</scope></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:3.17.2:exe:${os.detected.classifier}</protocArtifact><pluginId>grpc-java</pluginId><pluginArtifact>io.grpc:protoc-gen-grpc-java:1.39.0:exe:${os.detected.classifier}</pluginArtifact>
<!--                    <protoSourceRoot>src/main/resources</protoSourceRoot>--><protoSourceRoot>你的文件路径</protoSourceRoot></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin></plugins></build>

配置好了之后,只需要点击项目的compile生命进程,就会自动在target中出现生成好的代码文件。

YoloProto:该文件声明了入参与回参的相关信息,不需要改动。
YoloFunGrpc:该文件声明了接口的信息,也不需要改动。

3.java代码调用封装

java代码主要是一套固定的代码套路,将生成的两个文件用起来,代码如下:

 @Slf4j
public class YoloFunClient {private final YoloFunGrpc.YoloFunBlockingStub blockingStub;private final  YoloFunGrpc.YoloFunStub asyncStub;public YoloFunClient(String host, int port) {this(ManagedChannelBuilder.forAddress(host, port).usePlaintext());}public YoloFunClient(ManagedChannelBuilder<?> channelBuilder) {ManagedChannel channel = channelBuilder.build();blockingStub = YoloFunGrpc.newBlockingStub(channel);asyncStub = YoloFunGrpc.newStub(channel);}/*** 初始化模型* @param id* @param cfg* @param data* @param weights* @return*/public YoloProto.InitReply init(String id, String cfg,String data,String weights){//构建对象YoloProto.InitRequest.Builder builder = YoloProto.InitRequest.newBuilder();builder.setId(id);builder.setCfg(cfg);builder.setData(data);builder.setWeights(weights);YoloProto.InitRequest request = builder.build();//发送请求return blockingStub.init(request);}/*** 识别图像* @param id* @param path* @return*/public YoloProto.DetectionReply detection(String id, String path , String detectImgPath){//构建对象YoloProto.DetectionRequest.Builder builder = YoloProto.DetectionRequest.newBuilder();builder.setId(id);builder.setPath(path);builder.setDetectFilePath(detectImgPath);YoloProto.DetectionRequest request = builder.build();//发送请求return blockingStub.detection(request);}/*** 释放模型* @param id* @return*/public YoloProto.FreeReply free(String id){//构建对象YoloProto.FreeRequest.Builder builder = YoloProto.FreeRequest.newBuilder();builder.setId(id);YoloProto.FreeRequest request = builder.build();//发送请求return blockingStub.free(request);}

用的过程中记住,入参和回参在yoloproto文件中,触发接口相关的在grpc文件中。

4.正式使用套路

可以在spring的config对象中,return一个这样的bean,然后各处就可以注入使用了。

    @Beanpublic YoloFunClient getYoloFunClient(){log.debug("YoloFunClient初始化");return new YoloFunClient(rpc_address,rpc_port);}

注意事项

1.一个版本的proto文件对应一个版本的java代码,不存在兼容这个概念,必须严格对应。
2.兼容的程度,精细到大小写,大小写对不上都没办法进行连接。

java实现grpc相关推荐

  1. Java 实现grpc实例--json转protobuf

    java和python使用grpc交互 参考文章: https://blog.csdn.net/zhj_fly/article/details/82684970 如上链接中讲的已经很清楚了,相同的内容 ...

  2. java版gRPC实战之五:双向流

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <java版gRPC实战>全系列链接 用p ...

  3. java版gRPC实战之四:客户端流

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <java版gRPC实战>全系列链接 用p ...

  4. java版gRPC实战之三:服务端流

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos <java版gRPC实战>全系列链接 用p ...

  5. java版gRPC实战之一:用proto生成代码

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于<java版gRPC实战>系列 < ...

  6. grpc_模型服务:流处理与使用Java,gRPC,Apache Kafka,TensorFlow的RPC / REST

    grpc 机器学习/深度学习模型可以通过不同的方式进行预测. 我的首选方法是将分析模型直接部署到流处理应用程序(如Kafka Streams或KSQL )中. 您可以例如使用TensorFlow fo ...

  7. kafka grpc_模型服务:流处理与使用Java,gRPC,Apache Kafka,TensorFlow的RPC / REST

    kafka grpc 机器学习/深度学习模型可以通过不同的方式进行预测. 我的首选方法是将分析模型直接部署到流处理应用程序(如Kafka Streams或KSQL )中. 您可以例如使用TensorF ...

  8. 模型服务:流处理与使用Java,gRPC,Apache Kafka,TensorFlow的RPC / REST

    机器学习/深度学习模型可以通过不同的方式进行预测. 我的首选方法是将分析模型直接部署到流处理应用程序(如Kafka Streams或KSQL )中. 您可以例如使用TensorFlow for Jav ...

  9. Java 实现Grpc服务通信

    GRPC实现服务通信 grpc相关特性: gRPC 是一种现代开源高性能远程过程调用 (RPC) 框架,可以在任何环境中运行.它可以通过对负载平衡.跟踪.健康检查和身份验证的可插拔支持,有效地连接数据 ...

  10. java版gRPC实战之五:双向流,rabbitmq持久化原理

    responseObserver.onNext(DeductReply.newBuilder() .setCode(code) .setMessage(message) .build()); } @O ...

最新文章

  1. 深度学习核心技术精讲100篇(六十六)- 基于LXD的GPU算力虚拟化(附解决方案代码)
  2. java面向对象-------类属性和方法,不同类之间调用
  3. Ubuntu抛弃了Untiy转向Gnome,美化之路怎么办?不用怕咱一步一步大变身!
  4. Kafka基本概念与术语
  5. 【小样本·多分类】如何解决「小样本」+「多分类」问题?
  6. qq群管机器人php,常用几款QQ群管机器人软件功能和体验对比
  7. excel中怎样制作下拉菜单
  8. 啥是全栈程序员?更厉害?更有钱途?
  9. 微信朋友验证消息是什么来源_微信开启朋友验证什么意思
  10. DeepFace: Closing the Gap to Human-Level Performance in Face Verification
  11. mysql frm怎么打开_frm 文件怎么打开?
  12. ros-noetic-yocs-cmd-vel-mux
  13. python接入支付宝
  14. 新的放假规定,大年三十还得朝九晚五!
  15. SSL/TLS会话的流量分析
  16. BPR英文及中文全称
  17. freemaker生成doc文档(特殊字符导致异常)
  18. Java (过河卒)
  19. 最根本的穴位-会阴穴
  20. [C# 网络编程系列]专题五:TCP编程

热门文章

  1. 写写做数模竞赛的经验
  2. cocostudio html5,Cocostudio的简单使用:
  3. SAS 没有增强型编辑器控件
  4. 7个大一C语言必学的程序 / C语言经典代码大全
  5. c语言判断奇偶素数,用C语言如何判断素数
  6. oracle12c安装教程
  7. 2020计算机核心期刊,中国科技核心(2019–2020中文核心期刊目录)
  8. java 清屏函数_c++清屏函数是什么
  9. java 常用富文本编辑器_常用的六个富文本编辑器
  10. MAC系统下jmeter安装教程