本页面介绍如何解决在使用 Workflows 时可能遇到的问题。
部署错误
部署工作流后,Workflows 会检查源代码是否正确无误,并符合语言语法。 如果发现错误,Workflows 会返回该错误。最常见的部署错误类型包括:
- 引用未定义的变量、步骤或子工作流
- 语法不正确
- 缩进不正确
{、}、"、-或:缺失或无关紧要
例如,以下源代码抛出部署错误,因为返回语句引用了未定义的变量 varC:
- step1: assign: - varA: "Hello" - varB: "World" - step2: return: ${varC + varB}
以下 Google Cloud 控制台和 gcloud CLI 示例中使用了此不正确的源代码。
控制台
发生部署错误时,Workflows 会在修改工作流页面的横幅中显示出错提示:
出错提示会标记源代码中的问题,并尽可能指定错误的来源:
Could not deploy workflow: failed to build: error in step step2: error
evaluating return value: symbol 'varC' is neither a variable nor a
sub-workflow name (Code: 3)
gcloud
运行 gcloud workflows deploy 命令时,如果部署失败,Workflows 会向命令行返回错误消息。错误消息会标记源代码中的问题,尽可能指定错误来源:
ERROR: (gcloud.workflows.deploy) [INVALID_ARGUMENT] failed to build:
error in step step2: error evaluating return value: symbol 'varC' is neither
a variable nor a sub-workflow name
如需解决此问题,请修改工作流的源代码。在这种情况下,请参阅 varA 而不是 varC。
HTTP 403 服务账号权限错误
执行工作流或部署或更新工作流时,您可能会遇到 HTTP 403 (PERMISSION_DENIED) 错误。
执行工作流时权限遭拒
当 HTTP 服务器响应错误代码 403 时,工作流执行会失败,因为工作流的服务账号缺少访问目标资源的权限。例如:
SERVICE_ACCOUNT does not have storage.objects.create access to the Google Cloud Storage object. Permission 'storage.objects.create' denied on resource (or it may not exist).
每个工作流在创建时都会与一个 Identity and Access Management (IAM) 服务账号相关联。如需解决此问题,请为工作流的服务账号授予一个或多个 IAM 角色,这些角色包含访问工作流所用资源所需的最低权限。例如,如需让工作流将日志发送到 Cloud Logging,请确保为执行工作流的服务账号授予包含 logging.logEntries.create 权限的角色。如需了解详情,请参阅向工作流授予访问 Google Cloud 资源的权限。
部署或更新工作流时权限请求被拒
当您部署或更新工作流时,如果您无权充当工作流的服务账号,则请求可能会失败,并显示 HTTP 403 (PERMISSION_DENIED) 错误。例如:
Permission 'iam.serviceaccounts.actAs' denied on service account PROJECT_NUMBER-compute@ (or it may not exist).
或
permission iam.serviceAccounts.ActAs is required on the workflow's new/current service account to set it or the workflow source contents
如需解决此问题,请向部署或更新工作流的主账号授予包含 iam.serviceAccounts.actAs 权限的角色,例如 Service Account User (roles/iam.serviceAccountUser)。根据操作,在以下服务账号上授予此角色:
- 仅更新工作流源代码(不更新服务账号):在与工作流关联的现有服务账号上授予该角色。
- 创建工作流、更新服务账号,或同时更新源代码和服务账号:向与工作流关联的新服务账号授予该角色。
如需了解详情,请参阅服务账号权限。
HTTP 404 No such object 或 Not found 错误
使用 Cloud Storage 连接器时,如果 HTTP 服务器响应错误代码 404,则工作流执行会失败。例如:
HTTP server responded with error code 404 in step "read_input_file", routine "main", line: 13 { "body": "Not Found", "code": 404, ... }
您应对对象名称进行网址编码,以使其具备路径安全性。当适用字符出现在请求网址的对象名称或查询字符串中时,您可以使用 url_encode 和 url_encode_plus 函数对这些字符进行编码。例如:
- init: assign: - source_bucket: "my-bucket" - file_name: "my-folder/my-file.json" - list_objects: call: googleapis.storage.v1.objects.get args: bucket: ${source_bucket} object: ${text.url_encode(file_name)} alt: media result: r - returnStep: return: ${r}
如果您未对对象名称进行网址编码,并且存储桶包含文件夹,则请求将失败。如需了解详情,请参阅对网址路径部分进行编码和 Cloud Storage 命名注意事项。
HTTP 429 Too many requests 错误
可以并发运行的活跃工作流执行数存在上限。此配额用尽后,如果执行作业积压功能已停用,或者已达到积压执行作业的配额,则任何新的执行作业都会失败,并返回 HTTP 429 Too many requests 状态代码。
借助执行积压,您可以在达到并发执行配额后将工作流执行排入队列。默认情况下,系统会为所有请求(包括由 Cloud Tasks 触发的请求)启用执行积压,但以下情况除外:
- 在工作流中使用
executions.run或executions.create连接器创建执行时,默认情况下会停用执行积压。您可以通过将执行的disableConcurrencyQuotaOverflowBuffering字段明确设置为false来进行配置。 - 对于由 Pub/Sub 触发的执行,执行积压功能处于停用状态,且无法配置。
如需了解详情,请参阅管理执行积压。
您还可以启用 Cloud Tasks 队列,以您定义的速率执行子工作流,并实现更好的执行速率;在这种情况下,您可能需要明确停用执行积压。
跨项目服务账号权限错误
如果您在尝试使用跨项目服务账号部署工作流时收到 PERMISSION_DENIED 错误,请确保未对您的项目强制执行 iam.disableCrossProjectServiceAccountUsage 布尔值限制条件,并且您已正确设置服务账号。如需了解详情,请参阅使用跨项目服务账号部署工作流。
资源名称必须符合 RFC 1123 的要求
当 HTTP 服务器响应错误代码 400 时,工作流执行失败。例如:
"description": "must conform to RFC 1123: only lowercase, digits, hyphens, and periods are allowed, must begin and end with letter or digit, and less than 64 characters."
如需解决此问题,请确保您的资源名称遵循 RFC 1123 中定义的 DNS 标签标准,并且在分配变量时,您正确串联了字符串和表达式。
例如,您不能像这样分配变量:- string: hello-${world}。
请改为执行以下操作:
YAML
- assign_vars: assign: - string: "hello" - string: ${string+" "+"world"}
JSON
[ { "assign_vars": { "assign": [ { "string": "hello" }, { "string": "${string+" "+"world"}" }, ] } } ]
包含英文冒号的表达式
在 YAML 中,如果冒号被解释为定义映射,则包含冒号的表达式可能会导致意外行为。虽然可以部署和执行工作流,但输出不会符合预期。
如果使用 Google Cloud 控制台创建工作流,则工作流无法在 Google Cloud 控制台中直观呈现,并且您可能会收到类似于以下内容的警告:
要解决此问题,您可以使用英文单引号将 YAML 表达式括起来:
推荐: '${"a: " +string(a)}'
不推荐: ${"a: " +string(a)}
使用非字母数字字符的映射键
访问包含非字母数字字符(例如 "special!key": value 中的感叹号)的映射键时,必须用引号将键名称括起来。如果键名未用引号括起来,则无法部署工作流。例如,如果您尝试部署以下源代码,系统会抛出 token recognition error:
- init: assign: - var: key: "special!key": bar - returnOutput: return: '${"foo" + var.key[special!key]}'
如需解决此问题,请改用以下代码来返回输出:
'${"foo" + var.key["special!key"]}'
列表中的多个表达式
在列表内使用多个表达式(如以下迭代范围示例)不是有效的 YAML:
[${rangeStart}, ${rangeEnd}])
您可以通过执行以下任一操作来解决此问题:
将列表放入表达式中:
${[rangeStart, rangeEnd]}用英文单引号将每个表达式括起来:
['${rangeStart}', '${rangeEnd}']
结果是一个包含两个值的列表,符合预期。
客户管理的加密密钥 (CMEK)
将 Cloud KMS 与 Workflows 搭配使用时,您可能会遇到错误。下表介绍了不同的问题以及如何解决这些问题。
| 问题 | 说明 |
|---|---|
权限 cloudkms.cryptoKeyVersions.useToEncrypt 被拒 |
提供的 Cloud KMS 密钥不存在,或者权限未正确配置。 解决方案:
|
| 密钥版本未启用 | 提供的 Cloud KMS 密钥版本已停用。
解决方案:重新启用 Cloud KMS 密钥版本。 |
| 密钥环区域与要保护的资源不匹配 | 提供的 KMS 密钥环区域与工作流的区域不同。
解决方案:使用来自同一区域的 Cloud KMS 密钥环和受保护的工作流。(请注意,它们可以位于不同的项目中。)如需了解详情,请参阅 Cloud KMS 位置和 Workflows 位置。 |
| 已超出 Cloud KMS 配额限制 | 已达到 Cloud KMS 请求的配额限制。
解决方案:限制 Cloud KMS 调用的数量或提高配额限制。如需了解详情,请参阅 Cloud KMS 配额。 |
使用 Cloud Run 连接器时找不到请求的实体
当 HTTP 服务器在尝试使用连接器方法 googleapis.run.v1.namespaces.jobs.create 时响应错误代码 404,您的工作流执行会失败。
此方法要求您指定 HTTP 端点的位置。例如 us-central1 或 asia-southeast1。如果您未指定位置,则会使用全球端点 https://run.googleapis.com;但是,此位置仅支持列表方法。
如需解决此问题,请确保在调用连接器时指定 location 参数。如需了解 Cloud Run Admin API 位置选项,请参阅服务端点。
资源限制
如果您遇到资源限制或 ResourceLimitError、MemoryLimitExceededError 或 ResultSizeLimitExceededError 等错误,可以通过清除变量来释放内存。例如,您可能需要释放后续步骤所需的内存。或者,您可能有一些调用,其结果您并不关心,您可以完全忽略这些结果。
YAML 缩进
YAML 缩进是有意义的,每个缩进级别至少应有两个空格。 缩进不足可能会导致错误,新级别应该在上一行文本开头的基础上缩进至少两个空格。例如,以下示例错误地指定了一个列表项,其中包含一个具有 stepName 和 call 项的映射:
- stepName: call: sys.log
相反,您应该将后续行缩进两个空格,以将 call 嵌套在 stepName 中:
- stepName: call: sys.log
请务必使用空格(而非制表符)来缩进行。