• grpc设置连接存活时间及服务端健康检查


    本文包括两方面:
    1,grpc如何设置连接存活时间
    2,如何在服务端检测连接是否存活

    目录

    背景

    分析

    服务端实现

    客户端如何实现


    背景

    你不希望这个连接一直存活下去,到了一定时间想让其强制关闭
    或者是担心客户端异常退出但服务端无法感知时,服务端会认为客户端依旧存在,这时候就需要服务端主动持续进行健康检查。

    分析

    源码中有这样一个结构体:

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


    其中defaultMaxConnectionIdle、MaxConnectionAge、MaxConnectionAgeGrace默认均为无穷大
    defaultMaxConnectionIdle:默认的最大空闲连接数
    MaxConnectionAge:默认的连接最大年龄
    MaxConnectionAgeGrace:MaxConnectionAgeGrace是 MaxConnectionAge之后的一个附加时间段,之后连接将被强制关闭。

    可以看出来MaxConnectionAge和MaxConnectionAgeGrace是一组同类型参数;

    那么无穷大到底是多少呢?

    1. defaultMaxConnectionIdle      = infinity
    2. defaultMaxConnectionAge       = infinity

    infinity是什么?

    1. infinity                      = time.Duration(math.MaxInt64)
    2. MaxInt64  = 1<<63 - 1

    也就是说如果你不人为的设置,且连接没有因外界因素被迫中断,正常情况下将一直无限存在;


    Time:会ping客户端以查看传输是否仍然存在,如果设置的值低于1s,则将使用最小值1s,不设置也是无穷大,无穷大意味着一直不会ping。
    Timeout:在ping进行keepalive检查后,服务器会等待一段时间Timeout,即使在连接关闭之后也没有看到任何活动。默认值是2小时。

    那么问题就可以解决了,只需设置最后两个参数即可。
    如何设置?

    如果你用过grpc,你一定见过grpc.NewServer()
    可以看看它的参数:

    func NewServer(opt ...ServerOption) *Server {}


    那么ServerOption都可以设置哪些功能?作者已经抠出来了,如下

    1. type serverOptions struct {
    2.     creds                 credentials.TransportCredentials
    3.     codec                 baseCodec
    4.     cp                    Compressor
    5.     dc                    Decompressor
    6.     unaryInt              UnaryServerInterceptor
    7.     streamInt             StreamServerInterceptor
    8.     chainUnaryInts        []UnaryServerInterceptor
    9.     chainStreamInts       []StreamServerInterceptor
    10.     inTapHandle           tap.ServerInHandle
    11.     statsHandler          stats.Handler
    12.     maxConcurrentStreams  uint32
    13.     maxReceiveMessageSize int
    14.     maxSendMessageSize    int
    15.     unknownStreamDesc     *StreamDesc
    16.     keepaliveParams       keepalive.ServerParameters
    17.     keepalivePolicy       keepalive.EnforcementPolicy
    18.     initialWindowSize     int32
    19.     initialConnWindowSize int32
    20.     writeBufferSize       int
    21.     readBufferSize        int
    22.     connectionTimeout     time.Duration
    23.     maxHeaderListSize     *uint32
    24.     headerTableSize       *uint32
    25.     numServerWorkers      uint32
    26. }

    我们经常用到的比如creds可以实现TLS认证、streamInt实现拦截器、keepaliveParams就是用来健康检查的;

    服务端实现

    经过一系列先分析观察,最终这样即可(grpc.Creds(creds)为增加的认证操作,可忽略):

    1. grpc.NewServer(grpc.Creds(creds), grpc.KeepaliveParams(keepalive.ServerParameters{
    2.         Time:    20 * time.Second,    // 每隔10秒ping一次客户端
    3.         Timeout: 5 * time.Second,   // 等待5秒ping再次确认,则认为连接已死
    4.     })), nil

    含义如下:每隔20秒ping一次客户端,若回包在5s内返回则认为正常,否则连接将被回收。
        
    那么如何监听检查结果呢?

    case <-stream.Context().Done()

    该通道如读到值则立即停止当前逻辑即可。


    客户端如何实现

    也一样哦,提供了ClientParameters参数:
     

    1. conn, err := grpc.Dial(target, grpc.WithTransportCredentials(cert), grpc.WithKeepaliveParams(keepalive.ClientParameters{
    2.         Time:                20 * time.Second,
    3.         Timeout:             5 * time.Second,
    4.         PermitWithoutStream: false,
    5.     }))

  • 相关阅读:
    Linux中的MFS分布式文件系统
    Ceres学习笔记004--使用Ceres进行2D圆拟合
    【NodeJs-5天学习】第二天篇② —— 网络编程(TCP、HTTP、Web应用服务)
    动态规划算法
    关于粉丝需要编译python版本的opencv-cuda11的方法(在ubuntu22.04平台编译,python3.6,cuda11.7)
    一文告知HTTP GET是否可以有请求体
    王杰C++day6
    数据库的事务、并发一致性、封锁
    IndexError: invalid index of a 0-dim tensor. Use `tensor.item()` in Python
    c语言进阶部分详解(《高质量C-C++编程》经典例题讲解及柔性数组)
  • 原文地址:https://blog.csdn.net/HYZX_9987/article/details/125564127