GRPC:千万不要随便升级

GRPC:千万不要随便升级问题现象 context deadline exceeded 服务 A 调服务 B 刚启动的时候正常 半个小时以后 再访问就异常了 访问不通 问题排查 1 使用的注册中心是 nacos 通过 web 控制面板查看服务列表 服务 B 正常 2 再看订阅者 也正常 3

欢迎大家来到IT世界,在知识的湖畔探索吧!

GRPC:千万不要随便升级



欢迎大家来到IT世界,在知识的湖畔探索吧!

问题现象

context deadline exceeded

欢迎大家来到IT世界,在知识的湖畔探索吧!

服务A调服务B,刚启动的时候正常,半个小时以后,再访问就异常了,访问不通……

问题排查

1、使用的注册中心是nacos,通过web控制面板查看服务列表,服务B正常

GRPC:千万不要随便升级

2、再看订阅者,也正常

GRPC:千万不要随便升级

3、这不就emo~~了,从报错看:的确是因为访问B不通,造成的超时异常。但是,通过nacos注册中心看,都是正常的。

4、另外一个项目,没有出现这个问题,这个是新项目。那就看go.mod 有哪些改动。

关键的点:kratos升级了、grpc升级了

GRPC:千万不要随便升级

查看升级日志、issue

  1. https://github.com/go-kratos/kratos/pull/3320
  2. https://github.com/go-kratos/kratos/issues/2641
  3. https://pkg.go.dev/google.golang.org/grpc#WithIdleTimeout
  4. https://blog.csdn.net/haihuanjack/article/details/
  5. https://github.com/grpc/grpc-go/issues/6829

定位问题

欢迎大家来到IT世界,在知识的湖畔探索吧!grpc.WithIdleTimeout(0)

空闲超时时间,默认值是:30 * time.Minute

GRPC:千万不要随便升级

/Users/go/pkg/mod/google.golang.org/grpc@v1.64.0/dialoptions.go:655

问题:grpc在v1.58引入了idle,空闲连接清理机制。默认值是30分钟,如果没有调用过,那么将置为idle,此时也没有断开,也不可使用。但是,在nacos的连接上没有特殊处理,所以,从注册中心排查,一切正常。但是,就是服务A无法正常访问服务B。

了解下WithIdleTimeout实现机制吧

1、先看参数说明

GRPC:千万不要随便升级

// WithIdleTimeout returns a DialOption that configures an idle timeout for the // channel. If the channel is idle for the configured timeout, i.e there are no // ongoing RPCs and no new RPCs are initiated, the channel will enter idle mode // and as a result the name resolver and load balancer will be shut down. The // channel will exit idle mode when the Connect() method is called or when an // RPC is initiated. // // A default timeout of 30 minutes will be used if this dial option is not set // at dial time and idleness can be disabled by passing a timeout of zero. // // # Experimental // // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release.

鉴于英文刚过8级,我还是选择了翻译软件:

欢迎大家来到IT世界,在知识的湖畔探索吧!// WithIdleTimeout返回一个DialOption,该DialOption为对象配置一个空闲超时 //通道。如果通道在配置的超时时间内处于空闲状态,即没有 //正在进行的rpc和没有新的rpc初始化,通道将进入空闲模式 //结果名称解析器和负载平衡器将被关闭。的 //当调用Connect()方法时,通道将退出空闲模式 //启动RPC。 //如果未设置此拨号选项,则使用默认的30分钟超时 //在拨号时间和空闲可以通过传递一个0的超时来禁用。 // #实验性的 //注意:此API是实验性的,可能会被更改或删除 //稍后发布。

2、如何实现的?

GRPC:千万不要随便升级

在文件名:clientconn.go,中开始NewClient,方法内调用了

idle.NewManager((*idler)(cc), cc.dopts.idleTimeout)

具体实现文件名:internal/idle/idle.go

GRPC:千万不要随便升级

触发这3个条件,则直接返回,否则开始启动定时器。

  • m.isClosed(): 检查对象 m 是否已经关闭。如果是关闭状态,则返回。
  • m.timeout == 0: 检查对象 m 的超时时间是否为 0。如果超时时间为 0,则返回。
  • m.actuallyIdle: 检查对象 m 是否处于空闲状态。如果处于空闲状态,则返回。
GRPC:千万不要随便升级

Grpc都有哪些状态

GRPC:千万不要随便升级

1、状态说明

  • Idle: 空闲状态。表示连接尚未建立或正在等待新的连接请求。
  • Connecting: 连接中状态。表示正在尝试建立连接。
  • Ready: 就绪状态。表示连接已经成功建立,可以进行数据传输。
  • TransientFailure: 临时故障状态。表示连接暂时失败,但可能会自动重试。
  • Shutdown: 关闭状态。表示连接已经被关闭,不再接受新的请求。

2、如何查看状态

欢迎大家来到IT世界,在知识的湖畔探索吧! // 查看状态 conn.GetState().String() // 获取状态变化 conn.WaitForStateChange(context.Background(), conn.GetState())

打印:

GRPC:千万不要随便升级

解决

临时关闭这个功能,不要定时检测空闲连接

GRPC:千万不要随便升级

总结

说归说,闹归闹。包该升级还是要升级,可能作者做了性能优化,可能修复了历史bug。当时,也有可能写了新bug。然后,才有机会发包,修复bug,循环往复……

只要不影响业务,还是鼓励大胆的尝试。在老板看来,技术只是工具,再牛13的技术,不能产生效益,都是扯淡~~

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/97620.html

(0)
上一篇 8小时前
下一篇 8小时前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信