gRPC 跨进程使用引发的问题
问题描述 在 Python 项目中使用 gRPC 进行通信,跨进程使用时,会出现阻塞或报错的情况(根据 gRPC.io 的版本不同,现象不同)。下面代码展示了一个跨进程使用的 DEMO,主进程向 30001 端口上的 gRPC 服务器发送请求,子进程也向相同的服务器发送请求。 def send(): channel = grpc.insecure_channel('localhost:30001') stub = message_pb2_grpc.GreeterStub(channel) response = stub.SayHello(message_pb2.HelloRequest(name='you')) print(f"Greeter client received 1: " + response.message) def main(): channel = grpc.insecure_channel('localhost:30001') stub = message_pb2_grpc.GreeterStub(channel) response = stub.SayHello2(message_pb2.HelloRequest(name='you')) print("Greeter client received 2: " + response.message) p = multiprocessing.Process(target=send) p.start() p.join() if __name__ == '__main__': main() 使用 gRPC.io 1.28.1 的情况下,会发生报错,主进程可以正常收到服务器的返回,但是子进程报 Socket operation on non-socket。 raise _InactiveRpcError(state) grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.UNAVAILABLE details = "Socket operation on non-socket" debug_error_string = "{"created":"@1587481625.192071231","description":"Error received from peer ipv6:[::1]:50051","file":"src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Socket operation on non-socket","grpc_status":14}" > 排查过程 根据代码,主进程和子进程分别创建了自己的 Channel,看上去逻辑没什么问题,没有什么思路,所以多尝试几种情况先测试一下吧。首先尝试了一下主进程和子进程请求不同的server,在 30001 和 30002 端口分别启动两个 gRPC Server,然后将客户端代码改为主进程请求 30001 端口,子进程请求 30002 端口,代码可以正常运行。测试到这里就更摸不着头脑了,代码明明写的是主进程子进程分别创建 Channel,现在的现象看上去像是在请求相同服务器的情况下,子进程复用了主进程的socket连接。gRPC 底层使用的是 HTTP2,而 HTTP2 使用了长连接,会不会是这个原因? ...