使用 Google 云 运行 的 Stackdriver Trace
Stackdriver Trace with Google Cloud Run
我一直在研究 Google Cloud 运行 上的 Stackdriver Trace 集成。我可以让它与代理一起工作,但我被一些问题困扰着。
鉴于
- Stackdriver 代理在一个小缓冲区中聚合跟踪并定期发送它们。
当云 运行 服务未处理请求时,- CPU 访问受到限制。
- Cloud 运行 服务没有关闭挂钩;你不能在关闭前清除缓冲区:容器只是得到一个 SIGKILL。这是您无法从应用程序中捕捉到的信号。
- 运行在请求-响应周期之外发送信息的后台进程似乎违反了Knative Container Runtime contract
- 日志数据的收集是documented,不需要我运行代理,但是遥测没有这样的解决方案。
- 我发现 one report 的人使用基于代理的方法 运行 在云上丢失痕迹
Google 是怎么做到的
我查看了 Cloud Endpoints ESP 的源代码(Cloud 运行 集成处于测试阶段),看看他们是否以不同的方式解决它,但使用了相同的模式:那里是一个带有痕迹(1s)的缓冲区,它会定期清除。
问题
虽然我的跟踪集成似乎在我的测试设置中工作,但我担心在生产环境中 运行 时跟踪不完整和丢失。
这是假设问题还是真实问题?
看来解决此问题的正确方法是将遥测数据写入日志,而不是使用代理进程。 Stackdriver Trace 支持吗?
你是对的。这是一个值得关注的问题,因为大多数跟踪库倾向于 sample/upload 在后台跟踪跨度。
由于 (1) 当容器不处理任何请求时,您的 CPU 几乎缩放到几乎为零,并且 (2) 容器实例可能由于不活动而随时被终止,因此您无法可靠地上传在您的应用程序中收集的那些跟踪跨度。正如您所说,由于我们没有完全停止 CPU,它有时可能会起作用,但它不会总是起作用。
看起来像某些 Stackdriver(and/or OpenTelemetry f.k.a。OpenCensus)库让您控制推送跟踪跨度的生命周期。
例如,这个用于 OpenCensus Stackdriver 导出器的 Go 包有一个 Flush()
方法,您可以在完成请求之前调用该方法,而不是依赖运行时定期上传跟踪跨度:https://godoc.org/contrib.go.opencensus.io/exporter/stackdriver#Exporter.Flush
我假设其他语言的其他跟踪库也公开了类似的 Flush() 方法,如果没有,请在评论中告诉我,这将是对这些库的有效功能请求。
Is this a hypothetical problem or a real issue?
如果您考虑云 运行 服务接收单个请求,那么这肯定是个问题,因为库将没有时间在容器实例的 CPU 之前刷新数据受到限制。
然而,在现实生活中的用例中:
- 云 运行 服务经常连续或频繁地接收请求,这意味着它的容器实例将:连续 CPU 或 CPU 不时可用.
- 丢弃痕迹是可以的:如果因为实例被关闭而没有收集到一些痕迹,很可能在这种情况发生之前您已经收集了足够多样化的样本集。此外,您可能只对聚合报告感兴趣,在这种情况下,收集单个跟踪并不重要。
请注意,Trace 库通常自己对要跟踪的请求进行采样,它们很少会跟踪 100% 的请求。
It looks like the right way to approach this is to write telemetry to logs, instead of using an agent process. Is that supported with Stackdriver Trace?
不,Stackdriver Trace 从发送到其 API 的跨度中获取数据。请注意,要将数据发送到 Stackdriver Trace,您可以使用 OpenCenss 和 OpenTelemetry 等库,不推荐使用专有的 Stackdriver Trace 库。
Cloud 运行 现在支持发送 SIGTERM。如果您的应用程序处理 SIGTERM,它将在关闭前获得 10 秒的宽限时间。
您可以利用这 10 秒来:
- 刷新有未发送数据的缓冲区
- 关闭与其他系统的连接
我一直在研究 Google Cloud 运行 上的 Stackdriver Trace 集成。我可以让它与代理一起工作,但我被一些问题困扰着。
鉴于
- Stackdriver 代理在一个小缓冲区中聚合跟踪并定期发送它们。 当云 运行 服务未处理请求时,
- CPU 访问受到限制。
- Cloud 运行 服务没有关闭挂钩;你不能在关闭前清除缓冲区:容器只是得到一个 SIGKILL。这是您无法从应用程序中捕捉到的信号。
- 运行在请求-响应周期之外发送信息的后台进程似乎违反了Knative Container Runtime contract
- 日志数据的收集是documented,不需要我运行代理,但是遥测没有这样的解决方案。
- 我发现 one report 的人使用基于代理的方法 运行 在云上丢失痕迹
Google 是怎么做到的
我查看了 Cloud Endpoints ESP 的源代码(Cloud 运行 集成处于测试阶段),看看他们是否以不同的方式解决它,但使用了相同的模式:那里是一个带有痕迹(1s)的缓冲区,它会定期清除。
问题
虽然我的跟踪集成似乎在我的测试设置中工作,但我担心在生产环境中 运行 时跟踪不完整和丢失。
这是假设问题还是真实问题?
看来解决此问题的正确方法是将遥测数据写入日志,而不是使用代理进程。 Stackdriver Trace 支持吗?
你是对的。这是一个值得关注的问题,因为大多数跟踪库倾向于 sample/upload 在后台跟踪跨度。
由于 (1) 当容器不处理任何请求时,您的 CPU 几乎缩放到几乎为零,并且 (2) 容器实例可能由于不活动而随时被终止,因此您无法可靠地上传在您的应用程序中收集的那些跟踪跨度。正如您所说,由于我们没有完全停止 CPU,它有时可能会起作用,但它不会总是起作用。
看起来像某些 Stackdriver(and/or OpenTelemetry f.k.a。OpenCensus)库让您控制推送跟踪跨度的生命周期。
例如,这个用于 OpenCensus Stackdriver 导出器的 Go 包有一个 Flush()
方法,您可以在完成请求之前调用该方法,而不是依赖运行时定期上传跟踪跨度:https://godoc.org/contrib.go.opencensus.io/exporter/stackdriver#Exporter.Flush
我假设其他语言的其他跟踪库也公开了类似的 Flush() 方法,如果没有,请在评论中告诉我,这将是对这些库的有效功能请求。
Is this a hypothetical problem or a real issue?
如果您考虑云 运行 服务接收单个请求,那么这肯定是个问题,因为库将没有时间在容器实例的 CPU 之前刷新数据受到限制。
然而,在现实生活中的用例中:
- 云 运行 服务经常连续或频繁地接收请求,这意味着它的容器实例将:连续 CPU 或 CPU 不时可用.
- 丢弃痕迹是可以的:如果因为实例被关闭而没有收集到一些痕迹,很可能在这种情况发生之前您已经收集了足够多样化的样本集。此外,您可能只对聚合报告感兴趣,在这种情况下,收集单个跟踪并不重要。
请注意,Trace 库通常自己对要跟踪的请求进行采样,它们很少会跟踪 100% 的请求。
It looks like the right way to approach this is to write telemetry to logs, instead of using an agent process. Is that supported with Stackdriver Trace?
不,Stackdriver Trace 从发送到其 API 的跨度中获取数据。请注意,要将数据发送到 Stackdriver Trace,您可以使用 OpenCenss 和 OpenTelemetry 等库,不推荐使用专有的 Stackdriver Trace 库。
Cloud 运行 现在支持发送 SIGTERM。如果您的应用程序处理 SIGTERM,它将在关闭前获得 10 秒的宽限时间。
您可以利用这 10 秒来:
- 刷新有未发送数据的缓冲区
- 关闭与其他系统的连接