首页 > 解决方案 > 为什么我们得到间歇性 gRPC 不可用/未知 RpcExceptions (C++/C#) 的任何想法

问题描述

我们使用 gRPC(版本 1.37.1)在 C# 进程和 C++ 进程之间进行进程间通信。两个进程都充当服务器和客户端,并使用 HTTP/2 传输通过 localhost 在同一台机器上运行。所有调用都使用阻塞同步一元调用而不是双向流。一些平均(ish)统计数据:

从 C++->C#:每秒 0-2 次调用,每分钟 0-40 次调用

从 C#->C++:每秒 0-5 次调用,每分钟 0-200 次调用

间歇性地,我们遇到了三个问题之一

C# 客户端对 C++ 服务器的调用返回一个 RpcException,通常是“HTTP2/Parse Error”、“Endpoint Read Failed”或“Transport Closed” C++ 客户端对 C# 服务器的调用返回一个 Unavailable 或 Unknown C++ 客户端 WaitForConnected 调用以检查通道在 500 毫秒后失败

最上面的一个是最常见的,也是我们拥有最多信息的地方。通常,我们会看到客户端收到 RPC 调用并遇到未知的帧类型。然后子通道进入关闭状态,一切通常重新连接正常。我们通常还会看到如下嵌入式错误(请注意,我们将 gRPC 源中的所有 FILE 实例替换为 FUNCTION):

win_read","file_line":307,"os_error":"系统检测到一个无效的指针地址,试图在调用中使用指针参数。\r\n","syscall":"WSARecv","wsa_error": 10014}]},{"created":"@1622120588.494000000","description":"大小为 262404 的帧溢出 65535 的本地窗口","file":"grpc_core::chttp2::TransportFlowControl::ValidateRecvData","file_line ":213}]}

我们所看到的未知帧类型是,它解析 HEADERS、WINDOW_UPDATE、DATA、WINDOW_UPDATE,然后得到一个 TCP: on_read 而没有相应的 READ,然后再次尝试解析。正是这个解析,看起来解析器在缓冲区中的偏移量错误,因为它获取了未知的帧类型、传入的帧大小和传入的 stream_id 都映射到它刚刚解析的 RPC 调用的中间。

以上是我们在为每个 rpc 调用创建一个新通道之前遇到的情况。虽然我们意识到从性能的角度来看它并不是很好,但我们已经看到自从做出改变以来稳定性有所提高。但是,我们仍然偶尔会遇到 rpc 异常。现在,最常见的是“Unknown”/“Stream Removed”,而不是上面列出的那些。

任何关于可能出错的想法都值得赞赏。我们已经打开了所有 gRPC 跟踪,甚至添加了它,并在 wireshark 中捕获了这个问题,但到目前为止还没有很好地表明是什么导致了传输关闭。有什么好的工具来监控套接字/端口的故障吗?

标签: socketstcpgrpcwinsockgrpc-c++

解决方案


推荐阅读