【问题标题】:gRPC Python quickstart/helloworld (greeter_client.py) is hanging before printing "Greeter client received: ..."gRPC Python quickstart/helloworld (greeter_client.py) 在打印“Greeter client received: ...”之前挂起
【发布时间】:2020-12-16 15:20:03
【问题描述】:

今天我想开始为我用 Python 编写的程序实现 gRPC 客户端和服务器。我已按照此处找到的教程进行操作:https://grpc.io/docs/languages/python/quickstart/

按照我的意思是我完全按照指示,按所写的方式输入每个命令。首先安装所有需求(在 conda 环境中),然后运行 ​​greeter_server.py 和 greeter_client.py。从技术上讲,该程序可以工作,但客户端程序在我的系统上挂起大约 30-40 秒,然后以简单的问候语“收到问候客户:您好!”作为响应。

所以我决定尝试这里的快速入门教程的 Go 版本:https://grpc.io/docs/languages/go/quickstart/。再次完全按照书面说明进行操作,构建并启动 go 服务器和 go 客户端,客户端程序在不到一秒的时间内响应“2020/08/27 12:48:24 Greeting: Hello world”。

go 版本的行为完全符合我的预期。然而,Python 版本需要将近一分钟才能回复一条简单的消息。有人知道发生了什么吗?

提前致谢。

编辑 1) - 我将用我刚刚完成的一些测试来补充原始问题。对于原文中的缺失,我深表歉意。所以,我一直在不同的机器上进行测试。在我的 Ubuntu 20 机器桌面上,问题存在。我可以简单地弹出一个终端,创建一个新的 conda 环境(我使用 Python 3.8 进行这些测试)。我执行快速入门教程。 Python 版本没有按预期工作(说服我一切正常工作需要很长时间)。我在 Go 中执行了快速入门,一切都运行良好。

我在我的 2011 mac book air 上测试了本教程,启动了一个终端,创建了一个新的 conda 环境 (3.8),与Go 版本。

所以我想知道是否有任何 gRPC 专家会对为什么会发生这种情况提出建议。我已经重启了我的机器并再次测试,我的 Ubuntu linux 机器上仍然存在问题。

编辑 2) - 我刚刚在 Ubuntu 20 云虚拟机上进行了类似的测试,一切正常(Python 和 Go 版本之间没有区别)。我尝试了我在网上找到的一个单独的随机“echo”gRPC Python 教程(与 gRPC 快速入门教程无关),问题仍然存在于我的本地。所以我相信这个问题可以与我的环境隔离。我迷路了。

编辑 3) - 我通过调试器运行客户端代码并添加断点。

from __future__ import print_function
import logging

import grpc

import helloworld_pb2
import helloworld_pb2_grpc


def run():
    # NOTE(gRPC Python Team): .close() is possible on a channel and should be
    # used in circumstances in which the with statement does not fit the needs
    # of the code.
    with grpc.insecure_channel('localhost:50051') as channel: # added break
        stub = helloworld_pb2_grpc.GreeterStub(channel) # added break
        response = stub.SayHello(helloworld_pb2.HelloRequest(name='you')) # added break - HANGS ASSINING `response` OBJECT
    print("Greeter client received: " + response.message) # added break


if __name__ == '__main__':
    logging.basicConfig()
    run()

它挂在 print 语句之前,在 with 块内。在我的 Mac 上,我设置了相同的断点,调试器立即将响应对象分配给内存并打印。在我的 Ubuntu 机器上,调试器挂起试图分配 response = stub.SayHello(helloworld_pb2.HelloRequest(name='you')) 变量。我注意到 Cython 的使用可能是一个线索。

如果我中断了 greeter_client.py 进程,我会得到以下跟踪:

  File "greeter_client.py", line 37, in <module>
    run()
  File "greeter_client.py", line 31, in run
    response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
  File "/home/james/.local/lib/python3.8/site-packages/grpc/_channel.py", line 824, in __call__
    state, call, = self._blocking(request, timeout, metadata, credentials,
  File "/home/james/.local/lib/python3.8/site-packages/grpc/_channel.py", line 813, in _blocking
    event = call.next_event()
  File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 338, in grpc._cython.cygrpc.SegregatedCall.next_event
  File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 169, in grpc._cython.cygrpc._next_call_event
  File "src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi", line 163, in grpc._cython.cygrpc._next_call_event
  File "src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi", line 63, in grpc._cython.cygrpc._latent_event
  File "src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi", line 42, in grpc._cython.cygrpc._next
KeyboardInterrupt

Edit 4) - 其中一位评论者提出了一个很好的建议来测试 python 客户端和 go 服务器组合(gRPC 允许零努力,go gRPC)。我执行了测试,Python 客户端的响应速度仍然很慢。 Go 客户端 - Go 服务器组合仍然很快。我相信这将其缩小到 Python 客户端的问题。谢谢@DazWilkin。为了完整起见,Go 客户端 - Python 服务器在

编辑 5) - 昨晚我完全重新安装了 Ubuntu 20.04 的最小版本。在新系统上,简单的 greeter_client.py 响应仍有大约 45 秒的延迟。 :(

【问题讨论】:

  • 您是否尝试过在两个版本上运行分析器来详细比较它们的性能?
  • 我没有尝试分析源。目前我假设有一个合理的解释和一些简单而明显的事情,我不明白为什么会发生这种情况。
  • 这是一个奇怪的问题。您是否尝试过(在本地)使用带有 Go 服务器的 Python 客户端和带有 Python 服务器的 Go 客户端? gRPC 的一个优点是它可以工作,并且可能有助于消除问题。
  • 谢谢@DazWilkin。我执行了您建议的测试和 Python 客户端 - Go 服务器。问题仍然存在。感谢您的建议。
  • 您解决了吗?也许尝试使用 virtualenv 而不是 conda?也许尝试将stub.SayHelloprint(response.message) 包装在while True 中,可能还带有time.sleep(1) 以消除启动时间?

标签: python go grpc


【解决方案1】:

这可能是所有包装语言(Python、Ruby、PHP、C#、Node)的常见问题。直接原因是战神名称解析器无法解析localhost的IPv6地址。可以通过指定环境变量GRPC_DNS_RESOLVER=native 来规避它,这会更改默认名称解析器。

这是 James 提供的日志中的挂起部分:

D0831 13:09:27.577593604    6445 dns_resolver_ares.cc:184]   (c-ares resolver) resolver:0x55eaa9dbd8a0 AresDnsResolver::StartLocked() is called.
D0831 13:09:27.577596674    6445 grpc_ares_wrapper.cc:645]   (c-ares resolver) request:0x55eaa9d99b80 c-ares grpc_dns_lookup_ares_locked_impl name=localhost:50051, default_port=https
D0831 13:09:27.577653493    6445 grpc_ares_ev_driver.cc:158] (c-ares resolver) request:0x55eaa9d99b80 grpc_ares_ev_driver_create_locked
D0831 13:09:27.577679913    6445 grpc_ares_wrapper.cc:200]   (c-ares resolver) request:0x55eaa9d99b80 create_hostbyname_request_locked host:localhost port:33731 is_balancer:0 qtype:AAAA
D0831 13:09:27.577725082    6445 grpc_ares_wrapper.cc:200]   (c-ares resolver) request:0x55eaa9d99b80 create_hostbyname_request_locked host:localhost port:33731 is_balancer:0 qtype:A
D0831 13:09:27.577736032    6445 grpc_ares_wrapper.cc:227]   (c-ares resolver) request:0x55eaa9d99b80 on_hostbyname_done_locked qtype=A host=localhost ARES_SUCCESS
D0831 13:09:27.577740632    6445 grpc_ares_wrapper.cc:273]   (c-ares resolver) request:0x55eaa9d99b80 c-ares resolver gets a AF_INET result: 
  addr: 127.0.0.1
  port: 50051

D0831 13:09:27.577745522    6445 grpc_ares_ev_driver.cc:392] (c-ares resolver) request:0x55eaa9d99b80 new fd: c-ares fd: 10
D0831 13:09:27.577748092    6445 grpc_ares_ev_driver.cc:98]  (c-ares resolver) request:0x55eaa9d99b80 Ref ev_driver 0x55eaa9cfd900
D0831 13:09:27.577750552    6445 grpc_ares_ev_driver.cc:406] (c-ares resolver) request:0x55eaa9d99b80 notify read on: c-ares fd: 10
D0831 13:09:27.577753342    6445 grpc_ares_ev_driver.cc:463] (c-ares resolver) request:0x55eaa9d99b80 ev_driver=0x55eaa9cfd900 grpc_ares_ev_driver_start_locked. timeout in 120000 ms
D0831 13:09:27.577755682    6445 grpc_ares_ev_driver.cc:98]  (c-ares resolver) request:0x55eaa9d99b80 Ref ev_driver 0x55eaa9cfd900
D0831 13:09:27.577763612    6445 grpc_ares_ev_driver.cc:227] (c-ares resolver) request:0x55eaa9d99b80 ev_driver=0x55eaa9cfd900. next ares process poll time in 1000 ms
D0831 13:09:27.577765852    6445 grpc_ares_ev_driver.cc:98]  (c-ares resolver) request:0x55eaa9d99b80 Ref ev_driver 0x55eaa9cfd900
D0831 13:09:27.577773282    6445 dns_resolver_ares.cc:448]   (c-ares resolver) resolver:0x55eaa9dbd8a0 Started resolving. pending_request_:0x55eaa9d99b80

此错误的跟踪问题位于 grpc#24018。对于仍然被此问题阻止的任何人,请随时在线程上发表评论,以便获得更多关注。

【讨论】:

    猜你喜欢
    • 2018-04-24
    • 2013-10-10
    • 1970-01-01
    • 2013-03-21
    • 2013-12-07
    • 2021-04-14
    • 2014-07-04
    • 2015-05-29
    • 2013-06-12
    相关资源
    最近更新 更多