问题排查

本页面介绍了您在使用 Cloud Storage 时可能会遇到的一些常见错误的问题排查方法。

如需了解影响 Google Cloud 服务(如 Cloud Storage)的区域或全球突发事件,请参阅 Google Cloud 状态信息中心

日志记录原始请求

使用 gsutil 或 Cloud Storage 客户端库等工具时,大部分请求和响应信息由这些工具处理。不过,有时查看详情有助于排查问题。按照以下说明为您的工具返回请求和响应标头:

控制台

查看请求和响应信息取决于您用来访问 Google Cloud Console 的浏览器。对于 Google Chrome 浏览器:

  1. 点击 Chrome 的主菜单按钮 ()。

  2. 选择更多工具

  3. 点击开发者工具

  4. 在显示的窗格中,点击网络标签页。

gsutil

在您的请求中使用全局 -D 标志。例如:

gsutil -D ls gs://my-bucket/my-object

客户端库

C++

  • 设置环境变量 CLOUD_STORAGE_ENABLE_TRACING=http 来获取完整的 HTTP 流量。

  • 设置环境变量 CLOUD_STORAGE_ENABLE_CLOG=yes 来获取每个 RPC 的日志记录。

C#

通过 ApplicationContext.RegisterLogger 添加日志记录器,并为 HttpClient 消息处理程序设置日志记录选项。如需了解详细信息,请参阅常见问题解答条目

Go

设置 GODEBUG=http2debug=1 环境变量。如需了解详情,请参阅 Go 软件包 net/http

如果您还要记录请求正文,请使用自定义 HTTP 客户端

Java

  1. 创建名为“logging.properties”的文件,其中包含以下内容:

    # Properties file which configures the operation of the JDK logging facility.
    # The system will look for this config file to be specified as a system property:
    # -Djava.util.logging.config.file=${project_loc:googleplus-simple-cmdline-sample}/logging.properties
    
    # Set up the console handler (uncomment "level" to show more fine-grained messages)
    handlers = java.util.logging.ConsoleHandler
    java.util.logging.ConsoleHandler.level = CONFIG
    
    # Set up logging of HTTP requests and responses (uncomment "level" to show)
    com.google.api.client.http.level = CONFIG
  2. 将 logging.properties 与 Maven 结合使用

    mvn -Djava.util.logging.config.file=path/to/logging.properties insert_command

如需了解详情,请参阅可插入式 HTTP 传输

Node.js

在调用 Node 脚本之前设置环境变量 NODE_DEBUG=https

PHP

使用 httpHandler 向客户端提供您自己的 HTTP 处理程序,并设置中间件来记录请求和响应。

Python

使用日志记录模块。例如:

import logging
import http.client

logging.basicConfig(level=logging.DEBUG)
http.client.HTTPConnection.debuglevel=5

Ruby

.rb file 顶部的 require "google/cloud/storage" 之后,添加以下内容:

ruby
Google::Apis.logger.level = Logger::DEBUG

错误代码

下面是您可能会遇到的常见 HTTP 状态代码。

301:永久移动

问题:我设置了一个静态网站,访问目录路径时返回一个空对象和 301 HTTP 响应代码。

解决方案:如果在访问目录(例如 http://www.example.com/dir/)时,您的浏览器下载了一个零字节对象,并且收到 301 响应代码,则您的存储分区很可能包含具有该名称的空对象。要检查是否存在此问题并解决问题,请执行以下操作:

  1. 在 Google Cloud Console 中,转到 Cloud Storage 的浏览器页面。

    转到浏览器

  2. 点击 Google Cloud Console 顶部的激活 Cloud Shell 按钮。激活 Cloud Shell
  3. 运行 gsutil ls -R gs://www.example.com/dir/。如果输出内容包含 http://www.example.com/dir/,则表明该位置存在一个空对象。
  4. 使用以下命令移除空对象:gsutil rm gs://www.example.com/dir/

您现在可以访问 http://www.example.com/dir/ 并让它返回该目录的 index.html 文件(而不是空对象)。

400:错误请求

问题:在执行可续传上传时,我收到了此错误和消息 Failed to parse Content-Range header.

解决方案:您在 Content-Range 标头中使用的值无效。例如,Content-Range: */* 无效,您应将其指定为 Content-Range: bytes */*。如果您收到此错误,表示当前的可续传上传不再有效,您必须启动新的可续传上传。

401:未经授权

问题:直接或通过 Cloud CDN 对公共存储分区发出的请求会失败,并返回 HTTP 401: UnauthorizedAuthentication Required 响应。

解决方案:检查您的客户端或任何中间代理是否没有将 Authorization 标头添加到对 Cloud Storage 发出的请求中。任何包含 Authorization 标头(即使该标头为空)的请求都将作为一项身份验证尝试进行验证。

403:帐号已停用

问题:我尝试创建存储分区,但收到 403 Account Disabled 错误。

解决方案:此错误表示您没有为关联项目启用结算功能。如需了解启用结算功能的步骤,请参阅为项目启用结算功能

如果已启用结算功能,但是您仍然收到此错误消息,您可以与支持部门联系并提供您的项目 ID 和问题描述。

403:已禁止

问题:我应该有权限访问特定的存储桶或对象,但如果您尝试执行此操作,我会收到 403 - Forbidden 错误,并显示类似于以下内容的消息:example@email.com does not have storage.objects.get access to the Google Cloud Storage object

解决方案:您缺少完成请求所需的存储桶或对象的 IAM 权限。如果您预期能够发出请求但无法做到,请执行以下检查:

  1. 错误消息中提及的授权对象是否是您预期收到的错误消息?如果错误消息中提及了意外的电子邮件地址或“匿名调用者”,则表示您的请求未使用预期的凭据。这可能是因为您用于发出请求的工具是使用其他别名或实体的凭据设置的,或者这可能是因为该请求是服务帐号代表您发出的。

  2. 错误消息中提及的权限是否是您需要的权限?如果不是预期的权限,可能是因为您正在使用的工具需要额外的访问权限才能完成您的请求。例如,为了批量删除存储桶中的对象,gsutil 需要先构建存储桶中要删除的对象的列表。批量删除操作的这一部分需要 storage.objects.list 权限,鉴于目标是删除对象,这通常只需要 storage.objects.delete 权限,因此您可能会感到意外。如果这是出现错误消息的原因,请确保您具有拥有其他必要权限的 IAM 角色

  3. 您是否被授予预期资源或父资源的 IAM 角色?例如,如果您被授予项目的 Storage Object Viewer 角色,并且您尝试下载对象,请确保该对象位于项目中的存储桶中:您可能会无意中拥有其他项目的 Storage Object Viewer 权限。

403:已禁止

问题:我正在从 storage.cloud.google.com 下载我的内容,我在浏览器中使用网址访问该对象时收到 403: Forbidden 错误:

https://storage.cloud.google.com/BUCKET_NAME/OBJECT_NAME

解决方案:使用 storage.cloud.google.com 下载对象称为经过身份验证的浏览器下载,该过程使用基于 Cookie 的身份验证。如果您已配置 Cloud Audit Logs 中的数据访问审核日志以跟踪对象的访问权限,则该功能的一个限制是,除非被跟踪的对象可公开读取,否则经过身份验证的浏览器下载不能用于下载被跟踪的对象。试图对非公开对象使用经过身份验证的浏览器下载会导致 403 响应。存在此限制是为了防止 Google ID(用于基于 Cookie 的身份验证)钓鱼式攻击。

为避免此问题,请执行以下某项操作:

  • 使用直接 API 调用(支持未经身份验证的下载),而不是使用经过身份验证的浏览器下载。
  • 停用用于跟踪受影响对象的访问权限的 Cloud Storage 数据访问审核日志。请注意,数据访问审核日志在项目级层或更高级层设置,并且可以在多个级层同时启用。
  • 设置豁免项以从数据访问审核日志跟踪中排除特定用户,使这些用户能够执行经过身份验证的浏览器下载。
  • 通过向 allUsersallAuthenticatedUsers 授予读取权限,将受影响的对象设为可公开读取。数据访问审核日志不会记录对公开对象的访问。

409:冲突

问题:我尝试创建存储分区,但收到以下错误:

409 Conflict. Sorry, that name is not available. Please try a different one.

解决方案:您尝试使用的存储分区名称(例如 gs://catsgs://dogs)已被占用。Cloud Storage 使用全局命名空间,因此您不能将存储分区命名为与现有存储分区相同的名称。请选择未使用的名称。

429:请求数过多

问题:我的请求被拒绝,并显示 429 Too Many Requests 错误。

解决方案:您即将达到 Cloud Storage 允许的给定资源的请求数限制。如需了解 Cloud Storage 的限制,请参阅 Cloud Storage 配额。如果您的工作负载每秒对存储桶发出 1000 个请求,请参阅请求速率和访问分配准则来了解最佳做法,包括逐步增加工作负载并避免使用顺序文件名。

诊断 Google Cloud Console 错误

问题:使用 Google Cloud Console 执行操作时,我收到了一条一般性错误消息。例如,我在尝试删除存储分区时看到错误消息,但看不到操作失败的原因。

解决方案:使用 Google Cloud Console 的通知查看有关失败操作的详细信息:

  1. 点击 Google Cloud Console 顶部的通知按钮。

    通知

    下拉列表会显示 Google Cloud Console 最近执行的操作。

  2. 点击您要详细了解的操作项。

    此时将打开一个页面,其中显示了有关该操作的详细信息。

  3. 点击各行即可展开详细的错误信息。

    以下是一个失败存储分区删除操作的错误信息示例,该示例说明了存储分区保留政策阻止删除存储分区。

    存储分区删除错误详情

gsutil 错误

下面是您可能会遇到的常见 gsutil 错误。

gsutil stat

问题:我尝试使用 gsutil stat 命令来显示子目录的对象状态,但收到错误。

解决方案:Cloud Storage 使用平面命名空间将对象存储到存储分区中。 虽然您可以在对象名称中使用斜杠(“/”),使其看起来仿佛处于层次结构中,但 gsutil stat 命令会将尾部斜杠视为对象名称的一部分。

例如,如果运行命令 gsutil -q stat gs://my-bucket/my-object/,gsutil 将查询对象 my-object/(带有尾部斜杠)的相关信息,而不是对嵌套在 my-bucket/my-object/ 下的对象执行操作。除非您实际拥有具有该名称的对象,否则操作将失败。

对于子目录列出操作,请改为使用 gsutil ls

gcloud auth

问题:我尝试使用 gcloud auth 命令对 gsutil 进行身份验证,但仍无法访问我的存储桶或对象。

解决方案:您的系统可能同时安装了独立版和 Google Cloud CLI 版 gsutil。请运行 gsutil version -l 命令并检查 using cloud sdk 的值。如果为 False,则说明在您运行命令时,系统使用的是独立版 gsutil。您可以从系统中移除此版本的 gsutil,也可以使用 gsutil config 命令进行身份验证。

静态网站错误

设置存储分区来托管静态网站时可能遇到的常见问题如下。

HTTPS 传送

问题:我想在不使用负载平衡器的情况下通过 HTTPS 传送我的内容。

解决方案:您可以使用 https://storage.googleapis.com/my-bucket/my-object 等直接 URI 通过 HTTPS 传送静态内容。对于通过 SSL 使用自定义网域传送内容的其他选项,您可以:

域名验证

问题:我无法验证我的域名。

解决方案:通常,Search Console 中的验证过程会指示您将文件上传到您的网域,但是,如果没有相关的存储分区(您只能在执行域名验证后创建),您可能无法执行此操作。

在这种情况下,请使用域名提供程序验证方法来验证所有权。有关相关操作步骤,请参阅所有权验证。您可以在创建存储分区之前完成此验证。

页面无法访问

问题:我的网站提供的网页向我发出 Access denied 错误消息。

解决方案:检查对象是否已被公开共享。如果没有,请参阅公开数据以了解如何执行此操作。

如果您之前上传并共享了一个对象,但随后上传了该对象的新版本,则您必须以公开方式重新共享该对象。这是因为,上传新的版本后,公开权限会被替换。

权限更新失败

问题:我在尝试公开我的数据时收到错误消息。

解决方案:确保您拥有对象或存储分区的 setIamPolicy 权限。例如,您可以在 Storage Admin 角色中授予此权限。如果您拥有 setIamPolicy 权限,但仍然收到错误消息,则您的存储桶可能受到禁止公开访问制约,这可能不允许访问 allUsersallAuthenticatedUsers。您可以直接对存储分区设置禁止公开访问,也可以通过在更高级层设置的组织政策来强制实施这种禁止。

内容下载

问题:系统提示我下载我的页面内容,而不能在浏览器中查看。

解决方案:如果您将 MainPageSuffix 指定为对象并且该对象的类型不是网络内容,系统会提示网站访问者下载内容,而不是提供页面。如需解决此问题,请将 content-type 元数据条目更新为合适的值,例如 text/html。如需了解如何执行此操作,请参阅修改对象元数据

延迟时间

下面是您可能会遇到的常见延迟问题。此外,Google Cloud 状态信息中心提供有关影响 Google Cloud 服务(如 Cloud Storage)的区域或全球突发事件的信息。

上传或下载延迟时间

问题:我看到上传或下载的延迟时间有所增加。

解决方案:使用 gsutil perfdiag 命令从受影响的环境运行性能诊断。请考虑以下常见的上传和下载延迟时间原因:

  • CPU 或内存限制:受影响的环境的操作系统应使用工具来衡量本地资源消耗量,例如 CPU 用量和内存用量。

  • 磁盘 IO 限制:作为 gsutil perfdiag 命令的一部分,使用 rthru_filewthru_file 测试来衡量本地磁盘 IO 造成的性能影响。

  • 地理位置距离:性能可能受到 Cloud Storage 存储桶物理分离和不利环境的影响,尤其是在跨大洲的情况下。使用与不利环境位于同一区域的存储桶进行测试,可以确定地理位置分离对延迟时间的影响程度。

    • 如果适用,不利环境的 DNS 解析器应使用 EDNS(0) 协议,以便来自环境的请求通过适当的 Google Front End 前端路由。

gsutil 或客户端库延迟时间

问题:我在使用 gsutil 或某个客户端库访问 Cloud Storage 时看到延迟时间增加。

解决方案:gsutil 和客户端库会在有需要时自动重试请求,并且这种行为可能显著增加最终用户看到的延迟时间。使用 Cloud Monitoring 指标 storage.googleapis.com/api/request_count 查看 Cloud Storage 是否一致地提供可重试的响应代码,例如 4295xx

代理服务器

问题:我要通过代理服务器进行连接,我需要做些什么?

解决方案:如需通过代理服务器访问 Cloud Storage,您必须有权访问以下网域:

  • accounts.google.com,用于通过 gsutil config 创建 OAuth2 身份验证令牌
  • oauth2.googleapis.com,用于执行 OAuth2 令牌交换
  • *.googleapis.com,用于执行存储请求

如果您的代理服务器或安全政策不支持按网域列出白名单(而是需要按 IP 网络块列出白名单),我们强烈建议您为所有 Google IP 地址范围配置代理服务器。您可以通过在 ARIN 上查询 WHOIS 数据来查找地址范围。最佳做法是定期查看代理设置,以确保它与 Google 的 IP 地址相匹配。

我们不建议您使用单次查询 oauth2.googleapis.comstorage.googleapis.com 所获得的单个 IP 地址来配置代理。由于 Google 服务通过 DNS 名称进行呈现,而这些名称映射到了可能随时间变化的大量 IP 地址,因此,如果基于单次查询来配置代理,可能会导致您无法连接到 Cloud Storage。

如果您的请求通过代理服务器进行路由,您可能需要与网络管理员联系,以确保代理不会删除包含您的凭据的 Authorization 标头。如果没有 Authorization 标头,您的请求将被拒绝,并且您会收到 MissingSecurityHeader 错误。

后续步骤