【问题标题】:Tornado async endpoint does not worksTornado 异步端点不起作用
【发布时间】:2020-10-30 21:56:03
【问题描述】:

我有两个微服务:

  • 服务

具有两个端点的 Tornado 服务:/foo/bar

/foo

async def get(...):
   x = await test()
   return x

async def test():
    y = call to b service, FooBar rpc
    return y

/bar

 def get(...):
   return True
  • b 服务

带有rpc FooBar的gRPC服务

rpc FooBar

def FooBar(...):
   return requests.get("/bar")

如果客户端在服务中命中端点/foo

  1. 代码在 b 服务 中命中 rpc FooBar
  2. FooBar rpc 无法访问 服务 中的 /bar 端点,因为该服务已被阻止。

AFAIK,使用 x=await test() 应该可以防止我们这样的阻塞,我错过了什么?

【问题讨论】:

  • await 不会自动使您的代码非阻塞。那些 rpc 调用是异步的吗?如果没有,那么这将导致阻塞。
  • @xyres 是的 rpc 调用是同步的。但问题是tornado服务被阻止,而不是grpc服务
  • 是的,如果 rpc 调用不是异步的,那么它们将阻塞 tornado 进程(因为您正在从 tornado 进程中进行这些调用)。
  • @xyres 有没有办法“绕过”它有同步 rpc 调用?

标签: asynchronous tornado


【解决方案1】:

由于 rpc 调用不是异步的,它会阻塞 Tornado 进程。

您可以通过在单独的线程中运行 rpc 调用来避免阻塞主进程。

首先,使test() 方法成为常规函数,而不是协程(删除async 关键字)。

示例代码:

async def get(...): 
    x = await IOLoop.current().run_in_executor(None, test)
    return x

# regular function, not async
def test(...):
    # make calls
    return x

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多