续上一篇文章,我们上一篇讲到idle timeout 就会导致kratos consul发现失败问题,这遍讲讲idle 启动流程。
创建一个grpc Client我们是通过 grpc.DialContext 来创建的,跟随这个源码我们来跟踪下,何时创建idle 触发器。
改代码再 clientconn.go文件中,我们可以看到234行,调用了cc.idlenessMgr.ExitIdleMode(), 看描述 (创建名字解析器,负载均衡 等等)。于是我们接着进入 ExitIdleMode函数里面,不难发现里面调用了 m.enforcer.ExitIdleMode() 而该函数里面就会触发 我们自己的 name resolver buidler,也就是我们通过配置的 地址解析builder。接着这个函数往下就会看到m.resetIdleTimerLocked(m.timeout) 这个就是用于设置 idle timeout的,直接上这个函数源码
// resetIdleTimerLocked resets the idle timer to the given duration. Called
// when exiting idle mode or when the timer fires and we need to reset it.
func (m *Manager) resetIdleTimerLocked(d time.Duration) {
if m.isClosed() || m.timeout == 0 || m.actuallyIdle {
return
}
// It is safe to ignore the return value from Reset() because this method is
// only ever called from the timer callback or when exiting idle mode.
if m.timer != nil {
m.timer.Stop()
}
m.timer = timeAfterFunc(d, m.handleIdleTimeout)
}
可以看到 里面调用了 timeAfterFunc ,这个函数 实现就是根据参数d(多长时间后触发)来设置handleIdleTimeout 触发的时间点。到这里我们已经看到idle 建立流程。
默认的idle timeout 时间可以自己跟踪下,默认值在以下函数里面配置了,我们可以通过grpc 的dial option来修改该值。
func defaultDialOptions() dialOptions {
return dialOptions{
copts: transport.ConnectOptions{
ReadBufferSize: defaultReadBufSize,
WriteBufferSize: defaultWriteBufSize,
UseProxy: true,
UserAgent: grpcUA,
},
bs: internalbackoff.DefaultExponential,
healthCheckFunc: internal.HealthCheckFunc,
idleTimeout: 30 * time.Minute,
recvBufferPool: nopBufferPool{},
}
}