关于grpc 的keepalive 的一些知识

1. GRPC keepalive 的相关知识


参照这个连接

// ClientParameters is used to set keepalive parameters on the client-side.
// These configure how the client will actively probe to notice when a
// connection is broken and send pings so intermediaries will be aware of the
// liveness of the connection. Make sure these parameters are set in
// coordination with the keepalive policy on the server, as incompatible
// settings can result in closing of connection.
type ClientParameters struct {
	// After a duration of this time if the client doesn't see any activity it
	// pings the server to see if the transport is still alive.
	// If set below 10s, a minimum value of 10s will be used instead.
	Time time.Duration // The current default value is infinity.
	// After having pinged for keepalive check, the client waits for a duration
	// of Timeout and if no activity is seen even after that the connection is
	// closed.
	Timeout time.Duration // The current default value is 20 seconds.
	// If true, client sends keepalive pings even with no active RPCs. If false,
	// when there are no active RPCs, Time and Timeout will be ignored and no
	// keepalive pings will be sent.
	PermitWithoutStream bool // false by default.
}

// ServerParameters is used to set keepalive and max-age parameters on the
// server-side.
type ServerParameters struct {
	// MaxConnectionIdle is a duration for the amount of time after which an
	// idle connection would be closed by sending a GoAway. Idleness duration is
	// defined since the most recent time the number of outstanding RPCs became
	// zero or the connection establishment.
	MaxConnectionIdle time.Duration // The current default value is infinity.
	// MaxConnectionAge is a duration for the maximum amount of time a
	// connection may exist before it will be closed by sending a GoAway. A
	// random jitter of +/-10% will be added to MaxConnectionAge to spread out
	// connection storms.
	MaxConnectionAge time.Duration // The current default value is infinity.
	// MaxConnectionAgeGrace is an additive period after MaxConnectionAge after
	// which the connection will be forcibly closed.
	MaxConnectionAgeGrace time.Duration // The current default value is infinity.
	// After a duration of this time if the server doesn't see any activity it
	// pings the client to see if the transport is still alive.
	// If set below 1s, a minimum value of 1s will be used instead.
	Time time.Duration // The current default value is 2 hours.
	// After having pinged for keepalive check, the server waits for a duration
	// of Timeout and if no activity is seen even after that the connection is
	// closed.
	Timeout time.Duration // The current default value is 20 seconds.
}

grpc client 的keepalive 用来检测 client 创建的grpc channel 连接是不是可用的,如果超时,就会关掉这个channel 的连接
grpc server 的keepalive 用来检测 server 创建的grpc channel 连接是不是可用的,如果超时,就会关掉这个channel 的连接

在这里还需要特别注意一个问题, grpc client 的keepalive 的 时间设定 需要在server 允许范围内,否则,server 会认为你是捣蛋的,给你发送一个GOAWAY 消息,把和client 的连接强制关掉
这部分,具体我们来看grpc-go的相关定义:

// EnforcementPolicy is used to set keepalive enforcement policy on the
// server-side. Server will close connection with a client that violates this
// policy.
type EnforcementPolicy struct {
	// MinTime is the minimum amount of time a client should wait before sending
	// a keepalive ping.
	MinTime time.Duration // The current default value is 5 minutes.
	// If true, server allows keepalive pings even when there are no active
	// streams(RPCs). If false, and client sends ping when there are no active
	// streams, server will send GOAWAY and close the connection.
	PermitWithoutStream bool // false by default.
}

够清晰吧,所以在grpc server 端需要设置这个参数,来和client 端作匹配!

如果两者不匹配就会出现下面的错误

closing transport due to: connection error: desc = “error reading from server: EOF”, received prior goaway: code: ENHANCE_YOUR_CALM, debug data: “too_many_pings”

意思就是server 端说:”兄弟,你ping 的手速太快了,哥撑不住了,不带你玩了,滚吧!“。 说完就把连接诶给断了。

2. Java grpc server 的一些注意事项


如果要用java 写一个grpc server, 此时假定需要设定上面所述的匹配,应该要怎么做?
刚开始我们用的和官方demo一样的方式(io.grpc.ServerBuilder)创建server,但发现这个类io.grpc.ServerBuilder压根没有设置这个keepalive 参数的接口,后来在github 上看到这个issue:
https://github.com/grpc/grpc-java/issues/8991

NettyServerBuilder has the appropriate API. You’d need to use the APIs io.grpc.netty.NettyServerBuilder (and swap to grpc-netty) or the questionable io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder (to continue with grpc-netty). Neither option is great as grpc-netty-shaded is much preferred over grpc-netty but nominally it doesn’t really expose a public API.
As a short-term “get it working.” Using io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder is probably fair. But we need to add the keepalive methods to io.grpc.ServerBuilder.

确实NettyServerBuilder 有更丰富的接口,包含了许多设置keepalive 的api 接口。
其中就有限制client 的keepalive 的API, 让我们看下源码:

/**
   * Specify the most aggressive keep-alive time clients are permitted to configure. The server will
   * try to detect clients exceeding this rate and when detected will forcefully close the
   * connection. The default is 5 minutes.
   *
   * <p>Even though a default is defined that allows some keep-alives, clients must not use
   * keep-alive without approval from the service owner. Otherwise, they may experience failures in
   * the future if the service becomes more restrictive. When unthrottled, keep-alives can cause a
   * significant amount of traffic and CPU usage, so clients and servers should be conservative in
   * what they use and accept.
   *
   * @see #permitKeepAliveWithoutCalls(boolean)
   * @since 1.3.0
   */
  public NettyServerBuilder permitKeepAliveTime(long keepAliveTime, TimeUnit timeUnit) {
    checkArgument(keepAliveTime >= 0, "permit keepalive time must be non-negative: %s",
        keepAliveTime);
    permitKeepAliveTimeInNanos = timeUnit.toNanos(keepAliveTime);
    return this;
  }

Okay, 祝您好运!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值