问题排查

本页面介绍如何解决 Cloud Profiler 问题。

Google Cloud 项目配置错误

本部分列出了您可能遇到的配置问题,并提供了有关如何解决这些问题的建议。

Cloud Profiler API 已停用

如果您的 Google Cloud 项目未启用 Profiler API,则会出现以下错误:

failed to create a profile, will retry: rpc error: code = PermissionDenied
desc = Cloud Profiler API has not been used in project 012345 before or it is disabled.

要解决此问题,Google Cloud 项目必须启用 Profiler API:

  1. Enable the required API.

    Enable the API

  2. 如果系统显示 API 已启用,则表示此 API 已经启用。如未显示,请点击启用按钮。

调用者没有权限

如果您无权将性能剖析数据写入 Google Cloud 项目,则会发生以下错误:

failed to create a profile, will retry: rpc error: code = PermissionDenied
desc = The caller does not have permission.

要解决此问题,请让您的管理员授予您对该项目的额外权限。如需查看所需权限和角色的详细列表,请参阅访问权限控制

Node.js 错误

本部分列出了您在使用 Node.js 性能剖析代理时可能会遇到的问题,并提供了有关如何解决这些问题的建议。

Node.js:应用无法正常退出

Node.js 版性能剖析代理会干扰程序的正常退出。在程序中的所有任务都完成后,程序最多可能需要一个小时才能退出。

要解决此问题,请发出 SIGINT 信号(例如,使用 Ctrl-C)。当您发出 SIGINT 信号时,进程会正常终止。

Python 错误

本部分列出了您在使用 Python 性能剖析代理时可能会遇到的问题,并提供了有关如何解决这些问题的建议。

Python:NotImplementedError 异常

当应用在非 Linux 环境中运行时,在 start 函数执行期间会抛出以下异常:

NotImplementedError

要解决此问题,请在 Linux 环境中运行应用。

Python:ValueError 异常

当函数参数无效、无法从环境变量和参数中确定必要的信息,或 CPU 时间和实际用时性能剖析均被停用时,系统会在 start 期间抛出以下异常:

ValueError

要解决此问题,请检查以下所有内容:

  • 确保服务名称和版本符合服务名称和版本参数中定义的要求。
  • 如果启用了实际用时性能剖析,请确保从主线程调用 start
  • 确保您使用的是受支持的 Python 版本,并且已启用 CPU 时间性能剖析或实际用时性能剖析。如需了解详情,请参阅 start 函数
  • 如果您在 Google Cloud 之外运行,请检查是否已为 start 指定 project_id 参数。如需了解详情,请参阅 start 函数

Python:资源暂时不可用错误

启用 Profiler 后,错误日志包含以下条目:

BlockingIOError: [Errno 11] Resource temporarily unavailable
Exception ignored when trying to write to the signal wakeup fd

当应用注册信号唤醒文件描述符 signal.set_wakeup_fd 时,会出现这些消息。默认情况下,如果文件描述符的缓冲区填满,则系统会将一条警告记录到 stderr。

当 Cloud Profiler 收集性能剖析文件时,它会触发高频率信号,并可能导致信号文件描述符被填满。对于 GitHub 问题,请参阅 App Engine 上的 BlockingIOError

如需解决此问题,请执行以下某项操作:

  • 如果您的应用在信号中断时能够安全运行,则可以使用 Cloud Profiler。如果您使用的是 Python 3.7 或更高版本,并且想要停用警告消息,请将 warn_on_full_buffer=False 作为参数传递给 signal.set_wakeup_fd

  • 如果您的应用在信号中断时无法安全运行,我们建议您停止使用 Cloud Profiler。继续使用可能会导致错误日志中信号数丢失且条目过多。

缺少所有性能剖析文件

如果看不到任何性能剖析文件,可能有两个常见原因:

  • 服务的运行时间过短,不足以收集性能剖析文件。
  • 服务未配置身份验证。

要解决与运行时间过短相关的问题,请确保服务连续运行至少 3 分钟。

要解决与身份验证相关的问题,请确保性能剖析代理可以将数据写入您的 Google Cloud 项目:

  • 如果服务在 Google Cloud 上运行,身份验证是自动进行的,但在 Compute Engine 上部署容器的情况除外。在 Compute Engine 上部署容器时,您必须在 Profiler 代理 start 命令中指定您的 Google Cloud 项目 ID。如需查看相关说明,请参阅将代理关联到 Google Cloud 项目

  • 如果服务在 Google Cloud 之外运行,则您必须创建一个服务账号并将 Profiler 代理与您的 Google Cloud 项目关联。如需了解详情,请参阅在 Google Cloud 外部进行性能剖析

缺少特定类型的性能剖析文件

本部分列出了导致不收集一个或多个类型的性能剖析文件的特定配置。第一部分包含一般内容,其余部分则列出特定语言的问题。

常规信息

如果您想要查看特定的性能剖析文件类型,但没有该类型的性能剖析文件可用,请检查以下内容:

本页面的剩余部分介绍了各语言中导致不收集某种性能剖析文件类型的数据的配置。

Go:不收集 c-archives 的 CPU 时间性能剖析文件

如果构建 Go 应用并将 -buildmode 标志设置为 c-archivec-shared,则 CPU 时间性能剖析默认处于停用状态。堆、争用和线程性能剖析文件会被收集。如需了解详情,请参阅 GitHub 问题 #993:性能剖析器不为 c-archive 中的 Go 代码收集 CPU 数据

要解决此问题,请在服务调用 profiler.Start 之前启用 CPU 时间性能剖析文件收集,并添加对 signal.Notify(make(chan os.Signal), syscall.SIGPROF) 的调用。如需详细了解 signal.Notify,请参阅 func Notify

Java:启用多个性能剖析器时不收集堆性能剖析文件

您为 Java 应用启用了多个堆性能剖析器,但没有性能剖析文件。

Java 堆采样器被启用为独立代理功能。其结果是,一次只能使用一个性能剖析器。已新建错误,将 Java 扩展为支持多个堆性能剖析器。如需了解关于此错误,请参阅为堆采样机制添加多代理支持

要解决此问题,请启用一个性能剖析器。

Python:使用 uWSGI 时没有 CPU 时间和实际用时性能剖析文件

uWSGI 使用多个工作器处理请求时,默认行为是仅在主 (master) 进程中执行应用初始化。派生进程不执行初始化序列。

如果您在应用的初始化序列中配置性能分析代理(例如在 Django 应用的 AppConfig.ready() 方法中配置性能分析代理),则系统不会为派生进程配置性能分析代理。

要解决此问题,请将 lazy-apps 标志设置为 true,从而在所有工作器进程中执行应用初始化。

Python:使用 uWSGI 时有 CPU 时间性能剖析文件,但没有实际用时性能剖析文件

实际用时性能剖析器依赖于 Python 信号模块。 使用线程支持编译 Python 解释器时,默认配置会停用对派生进程的自定义信号处理。

要解决此问题,对于 uWSGI 应用,请将标志 py-call-osafterfork 设置为 true,以启用自定义信号处理。

Python:没有派生进程的性能剖析文件

性能剖析代理只能剖析启动代理的进程。

要解决此问题,如果您的应用会派生进程,并且您希望从派生进程收集性能剖析文件,请在派生后初始化代理。