【问题标题】:从 Pub/Sub 订阅中提取的 Google Cloud Function 引发异常 - 已超过截止日期
【发布时间】:2020-05-17 14:38:32
【问题描述】:

我在 Python 3.7 中有一个 Google Cloud Function,它以同步拉取模式从 Pub/Sub 订阅中读取数据。

在 1/hour 正常运行 24 小时后,它抛出了这个异常堆栈跟踪:

Traceback(最近一次调用最后一次):文件
"/env/local/lib/python3.7/site-packages/google/api_core/grpc_helpers.py",
第 57 行,在 error_remapped_callable
返回 callable_(*args, **kwargs) 文件“/env/local/lib/python3.7/site-packages/grpc/_channel.py”,第 824 行,
通话中
返回_end_unary_response_blocking(状态,调用,假,无)文件“/env/local/lib/python3.7/site-packages/grpc/_channel.py”,行
726,在_end_unary_response_blocking
raise _InactiveRpcError(state) grpc._channel._InactiveRpcError: <_inactiverpcerror of rpc> StatusCode.DEADLINE_EXCEEDED details = "已超过截止日期"
debug_error_string =
"{"created":"@1580454091.145703535","description":"收到的错误来自
同行
ipv4:74.125.202.95:443","file":"src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"截止日期
超过","grpc_status":4}"

上述异常是以下异常的直接原因:

Traceback(最近一次调用最后一次):文件
"/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py",
第 346 行,在 run_http_function
结果 = _function_handler.invoke_user_function(flask.request) 文件
"/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py",
第 217 行,invoke_user_function
返回 call_user_function(request_or_event) 文件“/env/local/lib/python3.7/site-packages/google/cloud/functions/worker.py”,
第 210 行,在 call_user_function
在迭代中返回 self._user_function(request_or_event) 文件“/user_code/main.py”,第 39 行
response = sub.pull(sub_path, MAX_MESSAGES) 文件“/env/local/lib/python3.7/site-packages/google/cloud/pubsub_v1/_gapic.py”,
第 40 行,在
fx = lambda self, *a, **kw: Wrapped_fx(self.api, *a, **kw) # noqa File
"/env/local/lib/python3.7/site-packages/google/cloud/pubsub_v1/gapic/subscriber_client.py",
第 1005 行,拉中
请求,重试=重试,超时=超时,元数据=元数据文件“/env/local/lib/python3.7/site-packages/google/api_core/gapic_v1/method.py”,
第 143 行,在 调用
返回 Wrapped_func(*args, **kwargs) 文件 "/env/local/lib/python3.7/site-packages/google/api_core/retry.py",
第 286 行,在 retry_wrapped_func
on_error=on_error,文件“/env/local/lib/python3.7/site-packages/google/api_core/retry.py”,
第 184 行,在 retry_target
返回目标()文件“/env/local/lib/python3.7/site-packages/google/api_core/timeout.py”,
第 214 行,在 func_with_timeout
返回 func(*args, **kwargs) 文件 "/env/local/lib/python3.7/site-packages/google/api_core/grpc_helpers.py",
第 59 行,在 error_remapped_callable
六.raise_from(exceptions.from_grpc_error(exc),exc)文件“”,第3行,在raise_from
google.api_core.exceptions.DeadlineExceeded:超过 504 截止日期

这是怎么回事?这是意料之中的还是某些配置问题的结果?如果符合预期,应该如何处理?

pull 上的文档 (view-source:https://googleapis.dev/python/pubsub/latest/subscriber/api/client.html) 并没有说明这是一个可能的异常。

我在拉取完成后立即确认消息。我一次只允许执行一个函数。我有 600 秒的确认截止日期。一次提取的消息块似乎少于 100 条。如果这是关于未能确认消息,那么错误似乎可以做得更好。

【问题讨论】:

  • 好像是there were no more messages to pull的意思。作为一种解决方法,我建议捕获异常并重试操作
  • 嗯,这似乎很奇怪。文档说 pull 可能会返回零消息,所以我不希望在这种情况下出现异常。
  • 是的,这似乎是 PubSub 库中的一个问题。显然在v0.45.0 版本中不会发生错误。我的猜测是这个问题与 return_immediately 的行为有关。此标志已被弃用,并且行为设置为等效于 return_immediately=False,因此客户端在等待新消息时只是保持连接处于活动状态,直到底层 grpc 截止日期引发异常
  • 啊,明白了。我考虑过立即使用return,因为我只想拉出一批当前可用的所有东西,但我实际上没有指定它,应该是=False场景。但也许我应该设置超时,因为我让那个默认值。这很难,因为 Python 文档确实留下了很多猜测。

标签: google-cloud-platform google-cloud-functions google-cloud-pubsub


【解决方案1】:

当订阅中没有要读取的消息时,客户端会引发此异常。它是来自最新 PubSub 库版本 >= 1.0.0 的 known issue。如有必要,您可以降级到不存在此问题的版本 0.45.0。

但是,作为一种解决方法,您可以捕获 DeadlineExceeded 异常并再次重试该操作。此外,基于comment of Hemang,这里有一个小猴子补丁,您可以将其添加到正在运行的代码中,这可能有助于获得与版本 0.45.0 中相同的行为。

from google.cloud.pubsub_v1.gapic import subscriber_client_config as sub_config
sub_config.config['interfaces']['google.pubsub.v1.Subscriber']['retry_params']['messaging']['initial_rpc_timeout_millis'] = 25000

最后,请记住,在使用同步拉取时,having many outstanding pull requests helps lower the delivery latency,这反过来可能会导致拉取请求延迟更高(以及 DeadlineExceeded 错误)。虽然,如果延迟对应用程序至关重要,您可以考虑使用StreamingPull

【讨论】:

  • 谢谢,@Tlaquetzal
  • 很高兴为您提供帮助!
猜你喜欢
  • 2019-07-27
  • 2021-12-12
  • 2017-07-07
  • 2022-01-01
  • 2022-01-27
  • 2021-11-23
  • 2019-02-22
  • 2020-02-02
  • 2017-09-14
相关资源
最近更新 更多