我有一个应用程序,其中包括一个FlaskAPI服务器和一个工作器来处理来自PubSub的消息.在Kubernetes中,它们作为单独的容器运行在不同的pod 上.

我已经迁移到使用工作负载标识,以前我会挂载服务帐户的密钥文件并设置GOOGLE_APPLICATION_CREDENTIALS.但是,在使用工作负载标识时,对PubSub的调用会抛出一个错误.

一个关键因素似乎是从gevent升至monkey.patch_all().

以下是使用工作负载标识在容器上运行时的可重现示例:

from gevent import monkey
monkey.patch_all()

from google.cloud import pubsub_v1
client = pubsub_v1.SubscriberClient()
resp = client.pull(request={"subscription": "projects/abc/subscriptions/xyz", "max_messages": 1, "return_immediately": True})

这将导致:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/venv/lib/python3.8/site-packages/google/cloud/pubsub_v1/_gapic.py", line 40, in <lambda>
    fx = lambda self, *a, **kw: wrapped_fx(self.api, *a, **kw)  # noqa
  File "/opt/venv/lib/python3.8/site-packages/google/pubsub_v1/services/subscriber/client.py", line 1131, in pull
    response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
  File "/opt/venv/lib/python3.8/site-packages/google/api_core/gapic_v1/method.py", line 154, in __call__
    return wrapped_func(*args, **kwargs)
  File "/opt/venv/lib/python3.8/site-packages/google/api_core/retry.py", line 283, in retry_wrapped_func
    return retry_target(
  File "/opt/venv/lib/python3.8/site-packages/google/api_core/retry.py", line 190, in retry_target
    return target()
  File "/opt/venv/lib/python3.8/site-packages/google/api_core/grpc_helpers.py", line 72, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/opt/venv/lib/python3.8/site-packages/grpc/_channel.py", line 944, in __call__
    state, call, = self._blocking(request, timeout, metadata, credentials,
  File "/opt/venv/lib/python3.8/site-packages/grpc/_channel.py", line 933, 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/credentials.pyx.pxi", line 62, in grpc._cython.cygrpc._get_metadata
RuntimeError: cannot exit context: thread state references a different context object

您知道为什么在使用工作负载标识而不是密钥文件时,gevent中的monkey.patch_all()会 destruct 这一点吗?另外,我怎么才能解决这个问题而又能保留monkey.patch_all()美元呢?

推荐答案

日安,先生

您遇到的问题是由于GEvent和GRPC之间的冲突造成的,GRPC由Google Cloud发布/订阅客户端使用.看起来这个问题是由gEvent的猴子补丁引起的.

该问题是由GRPC使用线程本地存储(TLS)来处理上下文这一事实引起的.当GEvent Money修补线程模块时,它会扰乱GRPC的TLS实现,这就是您收到错误的原因.

Try doing
monkey.patch_all(thread=False)

Python相关问答推荐

Flask:如何在完整路由代码执行之前返回验证

如何将不同长度的新列添加到现有的框架中

Pandas 群内滚动总和

使用Python Great Expectations和python-oracledb

单击Python中的复选框后抓取数据

按 struct 值对Polars列表[struct[]]排序

无法导入已安装的模块

机器人与Pyton Minecraft服务器状态不和

使用Python Cerberus初始化一个循环数据 struct (例如树)(v1.3.5)

指示组内的rejected_time是否在creation_timestamp后5分钟内

如何根据情况丢弃大Pandas 的前n行,使大Pandas 的其余部分完好无损

Python多处理:当我在一个巨大的pandas数据框架上启动许多进程时,程序就会陷入困境

Pandas 在最近的日期合并,考虑到破产

如何让剧作家等待Python中出现特定cookie(然后返回它)?

_repr_html_实现自定义__getattr_时未显示

将pandas Dataframe转换为3D numpy矩阵

如何在python polars中停止otherate(),当使用when()表达式时?

try 将一行连接到Tensorflow中的矩阵

如何找出Pandas 图中的连续空值(NaN)?

Js的查询结果可以在PC Chrome上显示,但不能在Android Chrome、OPERA和EDGE上显示,而两者都可以在Firefox上运行