Stackdriver Trace 与 Google Cloud Run

Posted

技术标签:

【中文标题】Stackdriver Trace 与 Google Cloud Run【英文标题】:Stackdriver Trace with Google Cloud Run 【发布时间】:2020-03-28 04:28:48 【问题描述】:

我一直在深入研究 Google Cloud Run 上的 Stackdriver Trace 集成。我可以让它与代理一起工作,但我被一些问题所困扰。

鉴于此

Stackdriver 代理将跟踪汇总到一个小缓冲区中并定期发送。 当 Cloud Run 服务未处理请求时,CPU 访问受到限制。 Cloud Run 服务没有关闭挂钩;您无法在关闭之前清除缓冲区:容器只会获得SIGKILL。这是您无法从应用程序中捕获的信号。 运行在请求-响应周期之外发送信息的后台进程似乎违反了Knative Container Runtime contract 日志数据的集合是documented,不需要我运行代理,但是遥测没有这样的解决方案。 我发现 one report 有人使用基于代理的方法在 Cloud Run 上丢失了踪迹

Google 是如何做到的

我查看了 Cloud Endpoints ESP 的源代码(Cloud Run 集成处于测试阶段),看看他们是否以不同的方式解决它,但使用了相同的模式:有一个带有跟踪的缓冲区( 1s) 并定期清除。

问题

虽然我的跟踪集成似乎在我的测试设置中工作,但当我在生产环境中运行它时,我担心不完整和丢失的跟踪。

这是假设问题还是实际问题?

看起来解决此问题的正确方法是将遥测数据写入日志,而不是使用代理进程。 Stackdriver Trace 支持吗?

【问题讨论】:

写得真好!!!好的!谢谢你。 相关:***.com/questions/58261080/… 似乎有一个功能要求 Cloud Run 在 SIGKILL 之前发送一个 SIGTERM:issuetracker.google.com/issues/131849051 该功能实际上正在推出。 【参考方案1】:

这是一个假设的问题还是一个真实的问题?

如果您认为 Cloud Run 服务接收单个请求,那么这肯定是一个问题,因为在容器实例的 CPU 受到限制之前库将没有时间刷新数据。

然而,在现实生活中的用例:

Cloud Run 服务经常连续或频繁地接收请求,这意味着它的容器实例将要么:持续拥有 CPU,要么不时拥有可用的 CPU。 可以删除跟踪:如果由于实例被关闭而未收集到某些跟踪,则很可能在此之前您已经收集了足够多样化的样本集。此外,您可能只对汇总报告感兴趣,在这种情况下,收集单个跟踪并不重要。

请注意,Trace 库通常自己对要跟踪的请求进行采样,它们很少跟踪 100% 的请求。

看起来解决此问题的正确方法是将遥测数据写入日志,而不是使用代理进程。 Stackdriver Trace 支持吗?

不,Stackdriver Trace 从发送到其 API 的 span 中获取数据。请注意,要将数据发送到 Stackdriver Trace,您可以使用 OpenCenss 和 OpenTelemetry 等库,但不推荐使用专有的 Stackdriver Trace 库。

【讨论】:

我认为这种假设在使用 Cloud Run 进行批处理/cron 作业(例如,每天一次或每 2 小时一次)等用例中会失效。您收到一个请求,将采样率设置为 100%,但在请求完成后,您很有可能会错过每天一次的跟踪数据。 Cloud Run 现在支持 SIGTERM(见答案)【参考方案2】:

你是对的。这是一个值得关注的问题,因为大多数跟踪库都倾向于在后台采样/上传跟踪跨度。

由于 (1) 当容器未处理任何请求时,您的 CPU 几乎缩放到零,并且 (2) 容器实例可能由于不活动而随时终止,因此您无法可靠地上传在您的应用程序。正如你所说,它有时可能会起作用,因为我们没有完全停止 CPU,但它并不总是有效。

似乎某些 Stackdriver(和/或 OpenTelemetry f.k.a. OpenCensus)库可让您控制推送跟踪跨度的生命周期。

例如,OpenCensus Stackdriver 导出器的这个 Go 包有一个 Flush() 方法,您可以在完成请求之前调用该方法,而不是依赖运行时定期上传跟踪跨度:https://godoc.org/contrib.go.opencensus.io/exporter/stackdriver#Exporter.Flush

我假设其他语言的其他跟踪库也公开了类似的 Flush() 方法,如果没有,请在 cmets 中告诉我,这将是对这些库的有效功能请求。

【讨论】:

当前的node.js跟踪代理库没有flush方法:( 我认为这将是对其 GitHub 存储库的有效问题请求。对于我们这些在谷歌工作的人来说,这也是一个有效的用例,可以对支持这一点的内容进行调查。感谢您提出。【参考方案3】:

Cloud Run 现在支持发送 SIGTERM。如果您的应用程序处理 SIGTERM,它将在关闭前获得 10 秒的宽限时间。

您可以使用这 10 秒来:

刷新具有未发送数据的缓冲区 关闭与其他系统的连接

文档:Container runtime contract

【讨论】:

以上是关于Stackdriver Trace 与 Google Cloud Run的主要内容,如果未能解决你的问题,请参考以下文章

来自文件的 C# Stackdriver Trace 凭据

用于 Stackdriver Trace 的 Google Cloud Java 客户端

如何使用 Stackdriver Trace 在 App Engine Standard 中创建自定义 Span?

Spring-Cloud-Gateway 创建的初始 Trace 都命名为“/”,无论路径如何

Google StackDriver:如何将其他日志与跟踪日志关联(和嵌套)?

用于错误报告的Stackdriver监视指标?