Java与Go服务之间gGRPC调用失败问题排查。

73 篇文章 1 订阅

最近新接手了一个项目,被告知Java代码的gRPC客户端无法访问当前项目中Go代码的gRPC服务,个人在问题排查的过程中对gRPC的理解更深入了一层 。

项目背景

接手该项目后跟该项目相关人员多次沟通后得到如下背景信息:

  1. 该项目Go服务端采用的是2016年9月以前发布的gRPC 

  2. 项目组对官方提供的Go语言gRPC类库做了部分改造,但,由于改造该代码的工程师已经离职,目前没有人知道具体修改了什么

  3. 由于项目周期紧张,没有富余的人力处理该问题

  4. 目前Java与Go互相交互的接口不到10个,双方先采用HTTP交互

  5. 服务端总是需要维护两套接口,HTTP和gRPC接口,链路跟踪等公共组件都要适配两套接口,增加了维护成本

 

问题重现

  1. 采用官方提供的Java gRPC客户端实例代码版本号为1.18.0,稍做改造访问现有的Go服务端,客户端请求发出后被hang直到达到客户端设置的连接超时后断开,Java客户端和Go服务端没有任何输出信息

  2. 抓包看包文发现在完成TCP的3次握手后,客户端发送了第一HTTP2的包文后,没有收到服务端的任何回复,整个过程被hang;初步估计是双方采用的HTTP2协议不兼容

  3. 采用低版本的Java gRPC, 调研发现Java的gRPC在2016年9月以前的最新版本是1.0.0,所以从1.0.0开始测试,最终发现0.9.0可以完成正常请求

 

问题原因

调研发现0.9.0版本的Java gRPC依赖了4.1.0.Beta6的Netty,该Netty版本发布于2015年9月, 而HTTP2在2015年有多次修订,版本号也升级到了17;个人估计该版本的Netty是根据HTTP2修订版17以前的规范实现的,而且该版本为Beta版,导致跟其它语言的协议存在某些差异。

其它问题

如果我们采用了0.9.0版本的Java gRPC会带来一些其它的问题:

  1. 现有的Java项目框架采用springcloud2.0.0,该版本依赖了Netty的4.1.27.Final版本,项目集成后会出现版本冲突导致各种异常出现

  2. 该版本的Java gRPC缺失部分重要的特性,比如:nameresolver,负载均衡,等...

  3. 最终还是要升级到新版本

 

解决方案

综合沟通下来最好的方案就是Go服务端升级gRPC到新版本 ,但是团队将官方代码改造后已经无法做到无缝升级,必须要做部分改造才能投入生产;目前生产环境运行的Go服务超过50+,而且大部分是核心服务;改造后需要充分的测试,总体成本太大,而且目前没有更多的资源投入。最终决定才有用低版本的Java gRPC ,采用以下的措施应对低版本面临的问题:

  1. 所有的Java项目提供统一的parent pom文件,所有的版本信息在parent pom的dependencyManagement中维护,子项目不显示声明引入的Jar包版本号 

  2. 增加新功能:nameresolver,负载均衡,兼容Go服务的服务发现,等...

 

一点思考

我们在技术选型的不能过于保守也不能过于激进;太过保守不能充分利用新技术的优势,甚至会影响到团队士气;太过激进会遭遇太多的不确定性,面临着遇到问题没有先例可以参考,遭遇新的bug,等;所以,在团队没有足够的技术支撑的情况下,我不太建议生产环境采用1.0以下的版本。作为技术人员应该随时关注业界的新技术,但在生产环境采用新技术前必须考虑清楚所面对的各种风险,包括以后的升级能否做到无缝升级。

品略图书馆 http://www.pinlue.com/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值