【问题标题】:go grpc server doesn't known client ungraceful deadgo grpc 服务器不知道客户端不优雅死了
【发布时间】:2017-12-21 09:53:00
【问题描述】:

我正在使用 go-grpc 创建双向流。当我拔下电缆时,服务器不知道客户端死了很长时间。在这种情况下如何检测客户端已消失???

【问题讨论】:

    标签: go grpc


    【解决方案1】:

    我遇到了和你一样的问题。在我的情况下,当我使用 Ctrl-C 终止我的测试客户端时,服务器很快检测到它,但是当我使用 Ctrl-Z(或者如果我切断微控制器的电源)时,服务器将永远关闭悬挂连接。您需要使用某种心跳来检查连接,使用诸如 gRPC 的 keepAlive 功能之类的东西。由于在 Envoy 后面使用 gRPC 时出现问题,我不得不创建自己的心跳消息并定期发送 (https://github.com/envoyproxy/envoy/issues/2086)

    【讨论】:

      【解决方案2】:

      您的GRPC 服务器端处理程序将在下次尝试向/从流发送Send/Recv 消息时了解客户端上下文取消:将返回错误:

      func (s *server) handler(stream your_service.Stream) error {
          if err := stream.Recv(); err != nil {
              // you will have context cancelation error here
          }
      }
      

      在某些情况下,明确检查上下文取消可能很有用:

      func (s *server) handler(stream your_service.Stream) error {
           // some logic
           select {
               case <-stream.Context().Done():
                   return stream.Context().Err()
               default:
           }
      }
      

      顺便说一句,你真的拔掉电缆吗?因为操作系统可能会以不同的方式处理它。为什么不使用任何现代虚拟化工具(例如 Docker)进行测试?

      【讨论】:

      • 就我而言,我无法使用stream.Recv() 进行检测。我确实使用了第二种方式,观察stream.Context().Done(),但是花了很长时间才注意到客户端已经消失了。我将实现我自己的心跳来让它工作。
      • 顺便说一句,是的,我真的拔掉了电缆!感谢您的提示,真的很有帮助。
      猜你喜欢
      • 2017-02-11
      • 1970-01-01
      • 1970-01-01
      • 2021-05-03
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 2020-06-25
      相关资源
      最近更新 更多