GCP PubSub mysteriously/silently 因 Cloud Functions 而失败
GCP PubSub mysteriously/silently failing with Cloud Functions
我有大约十几个 GCF 函数 (Python),其中 运行 每天一次。为了保持正确的顺序,我使用 PubSub。例如:
topic1 触发 function1 -> function1 运行s -> function1 向 topic2 写入消息 -> topic2 触发 function2 -> function2 运行s -> etc.
这个用例是低吞吐量,并且是一种非常直接(我认为)的方式,可以将 GCF 和 PubSub 一起使用以获得彼此的优势。这些函数使用 Python 中的 pubsub_v1
来发布消息。 IAM、权限等都没有问题。代码如下:
from google.cloud import pubsub_v1
# Publish message
publisher = pubsub_v1.PublisherClient()
topic2 = publisher.topic_path('my-project-name', 'topic2_id')
publish_message = '{short json message to be published}'
print('sending message ' + publish_message)
publisher.publish(topic2, publish_message.encode("utf-8"))
我使用以下方法部署 function1 和其他函数:
gcloud functions deploy function1 --entry-point=my_python_function --runtime=python37 \
--trigger-topic=topic1 --memory=4096MB --region=us-central1 \
--source="url://source-repository-with-my-code"
但是,最近我开始看到一些非常奇怪的行为。基本上,function1 运行s,日志看起来很棒,消息似乎已发布到 topic2...然后什么都没有。 function2 不会开始执行,也不会在日志中显示任何表明它已被触发的信息。没有表明成功或失败的日志。所以基本上看起来是:
- 尽管函数 1 以
Function execution took 24425 ms, finished with status: 'ok'
结束,但函数 1 到主题 2 的消息未发布
- 正在发布从 function1 到 topic2 的消息,但 topic2 没有触发 function2。
这是 PubSub 的预期行为吗?这些失败似乎完全是随机的。我花了几个月的时间,一切都非常可靠,现在突然间我不知道消息是否会被传递。似乎也很难跟踪这些 PubSub 消息的生命周期以查看它们究竟丢失在哪里。我已经阅读了有关死信主题等的文档,但我真的不明白如何设置使其易于跟踪的内容。
- 发送频率非常低的短消息“失败”是否正常?
- 有没有我遗漏的东西或我应该做的事情,例如在
publisher.publish()
电话中以确保更可靠的交付?
- 是否有一种透明的方式来查看正在发生的事情以及这些消息丢失的位置?设置一个新的订阅,我可以在控制台中查看它,看看哪些消息正在传递,哪些消息失败,类似这样的事情?
- 如果我需要 100%(或接近 100%)的可靠性,我应该放弃 GCF 和 PubSub 吗?什么更好?
这里的问题是您没有等待 publisher.publish
真正成功。此方法 returns 将来可能不会同步完成。如果要确保发布已成功完成,您需要对从 publish
:
返回的值调用 result()
future = publisher.publish(topic2, publish_message.encode("utf-8"))
future.result()
您还需要通过将 --retry
参数传递给 gcloud functions deploy
来确保在您的云函数上启用“失败时重试”。这样,如果发布失败,来自 topic1 的消息将被重新传递到云函数以再次尝试。
我有大约十几个 GCF 函数 (Python),其中 运行 每天一次。为了保持正确的顺序,我使用 PubSub。例如:
topic1 触发 function1 -> function1 运行s -> function1 向 topic2 写入消息 -> topic2 触发 function2 -> function2 运行s -> etc.
这个用例是低吞吐量,并且是一种非常直接(我认为)的方式,可以将 GCF 和 PubSub 一起使用以获得彼此的优势。这些函数使用 Python 中的 pubsub_v1
来发布消息。 IAM、权限等都没有问题。代码如下:
from google.cloud import pubsub_v1
# Publish message
publisher = pubsub_v1.PublisherClient()
topic2 = publisher.topic_path('my-project-name', 'topic2_id')
publish_message = '{short json message to be published}'
print('sending message ' + publish_message)
publisher.publish(topic2, publish_message.encode("utf-8"))
我使用以下方法部署 function1 和其他函数:
gcloud functions deploy function1 --entry-point=my_python_function --runtime=python37 \
--trigger-topic=topic1 --memory=4096MB --region=us-central1 \
--source="url://source-repository-with-my-code"
但是,最近我开始看到一些非常奇怪的行为。基本上,function1 运行s,日志看起来很棒,消息似乎已发布到 topic2...然后什么都没有。 function2 不会开始执行,也不会在日志中显示任何表明它已被触发的信息。没有表明成功或失败的日志。所以基本上看起来是:
- 尽管函数 1 以
Function execution took 24425 ms, finished with status: 'ok'
结束,但函数 1 到主题 2 的消息未发布
- 正在发布从 function1 到 topic2 的消息,但 topic2 没有触发 function2。
这是 PubSub 的预期行为吗?这些失败似乎完全是随机的。我花了几个月的时间,一切都非常可靠,现在突然间我不知道消息是否会被传递。似乎也很难跟踪这些 PubSub 消息的生命周期以查看它们究竟丢失在哪里。我已经阅读了有关死信主题等的文档,但我真的不明白如何设置使其易于跟踪的内容。
- 发送频率非常低的短消息“失败”是否正常?
- 有没有我遗漏的东西或我应该做的事情,例如在
publisher.publish()
电话中以确保更可靠的交付? - 是否有一种透明的方式来查看正在发生的事情以及这些消息丢失的位置?设置一个新的订阅,我可以在控制台中查看它,看看哪些消息正在传递,哪些消息失败,类似这样的事情?
- 如果我需要 100%(或接近 100%)的可靠性,我应该放弃 GCF 和 PubSub 吗?什么更好?
这里的问题是您没有等待 publisher.publish
真正成功。此方法 returns 将来可能不会同步完成。如果要确保发布已成功完成,您需要对从 publish
:
result()
future = publisher.publish(topic2, publish_message.encode("utf-8"))
future.result()
您还需要通过将 --retry
参数传递给 gcloud functions deploy
来确保在您的云函数上启用“失败时重试”。这样,如果发布失败,来自 topic1 的消息将被重新传递到云函数以再次尝试。