本文档介绍了如何对 JSON API 调用进行集中批处理以减少客户端在访问 Cloud Storage 时必须建立的 HTTP 连接数量。
概览
客户端建立的每个 HTTP 连接都会产生一定的开销。Cloud Storage JSON API 支持批处理,这样您的客户端就可以将多次 API 调用组合为一个 HTTP 请求。
在以下示例情况下,您可能需要使用批处理:
- 更新多个对象的元数据,例如权限。
- 删除多个对象。
在上述每种情况下,您都可以将这些调用组合成一个 HTTP 请求,而不是单独发送每次调用。请注意,所有内部请求都必须发送到 Cloud Storage JSON API。
单个批量请求中包含的调用不应超过 100 次。如果您需要的调用次数超过此值,请使用多个批处理请求。批处理请求总载荷必须小于 10MB。
批量详情
批量请求就是将多个 API 调用进行合并而形成的一个 HTTP 请求,您可以将此请求发送到 Cloud Storage 批量端点,即 https://storage.googleapis.com/batch/storage/v1
。本部分详细介绍了批处理语法,随后还会提供一个示例。
批量请求的格式
批量请求是一个包含多个 Cloud Storage JSON API 调用的标准 HTTP 请求。此主请求使用 multipart/mixed
内容类型。主 HTTP 请求中包含多个部分,每个部分均包含一个嵌套的 HTTP 请求。
各个部分都以其自身的 Content-Type: application/http
标头开头。
各部分还可以有一个可选的 Content-ID
标头。这些标头用于标记各部分的开头,但它们与嵌套的 HTTP 请求无关。这意味着,在服务器将批量请求拆分为单独的请求后,该部分的标头会被忽略。
各个部分的正文本身是一个完整的 HTTP 请求,各自有专用的动词、网址、标头和正文。这些 HTTP 请求只能包含网址的路径部分;完整网址可能会有未定义的行为。
外部批量请求的 HTTP 标头还应用于每个嵌套请求,但 Content-Type
之类的 Content-
标头除外。但是,如果您在外部请求和嵌套请求中都指定了特定的 HTTP 标头,则嵌套请求的标头值会替换该特定请求的外部批量请求标头值。
例如,如果您为特定嵌套请求提供了 Authorization
标头,则该标头将仅应用于指定该标头的请求。如果您为外部请求提供了 Authorization
标头,则该标头将应用于所有嵌套请求,除非这些嵌套请求将其替换为自身的 Authorization
标头。
当 Cloud Storage 收到批处理请求时,会将外部请求的查询参数和标头(如果适用)应用于各部分,然后将各部分视作单独的 HTTP 请求进行处理。
对批量请求的响应
Cloud Storage 响应是一条包含 multipart/mixed
内容类型的标准 HTTP 响应。该主响应的每个部分都是对批处理请求中一项请求的响应。响应的顺序与请求相同。
与请求中的所有部分一样,每个响应部分都包含一个完整的 HTTP 响应,包括状态代码、标头和正文。此外,和请求中的各部分一样,响应中的各部分均以 Content-Type
标头为前缀,用于标记各部分的开头。如需详细了解状态代码,请参阅 Cloud Storage JSON API 的 HTTP 状态和错误代码。
如果请求的某个特定部分具有 Content-ID
标头,则响应的对应部分也会有相同的 Content-ID
标头。响应的 Content-ID
标头以 response-
开头,后接请求中使用的 Content-ID
值,如示例中所示。
示例
以下批处理示例更新了 example-bucket
中三个对象的自定义元数据。
批量 HTTP 请求示例
HTTP
POST /batch/storage/v1 HTTP/1.1 Host: storage.googleapis.com Content-Length: 960 Content-Type: multipart/mixed; boundary="===============7330845974216740156==" Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg --===============7330845974216740156== Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: <b29c5de2-0db4-490b-b421-6a51b598bd22+1> PATCH /storage/v1/b/example-bucket/o/obj1 HTTP/1.1 Content-Type: application/json accept: application/json content-length: 31 {"metadata": {"type": "tabby"}} --===============7330845974216740156== Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: <b29c5de2-0db4-490b-b421-6a51b598bd22+2> PATCH /storage/v1/b/example-bucket/o/obj2 HTTP/1.1 Content-Type: application/json accept: application/json content-length: 32 {"metadata": {"type": "tuxedo"}} --===============7330845974216740156== Content-Type: application/http Content-Transfer-Encoding: binary Content-ID: <b29c5de2-0db4-490b-b421-6a51b598bd22+3> PATCH /storage/v1/b/example-bucket/o/obj3 HTTP/1.1 Content-Type: application/json accept: application/json content-length: 32 {"metadata": {"type": "calico"}} --===============7330845974216740156==--
客户端库
C++
C++ 客户端库不支持批量请求。
C#
C# 客户端库不支持批量请求。
Go
Go 客户端库不支持批量请求。
Java
如需了解详情,请参阅 Cloud Storage Java API 参考文档。
Node.js
Node.js 客户端库不支持批量请求。
PHP
PHP 客户端库不支持批量请求。
Python
如需了解详情,请参阅 Cloud Storage Python API 参考文档。
Ruby
如需了解如何使用 Ruby 发出批量请求,请参阅 Cloud Storage Ruby API 参考文档。
批量 HTTP 响应示例
此部分是对上一部分中的示例 HTTP 请求的响应。
HTTP/1.1 200 OK Content-Type: multipart/mixed; boundary=batch_pK7JBAk73-E=_AA5eFwv4m2Q= Date: Mon, 22 Jan 2018 18:56:00 GMT Expires: Mon, 22 Jan 2018 18:56:00 GMT Cache-Control: private, max-age=0 Content-Length: 3767 --batch_pK7JBAk73-E=_AA5eFwv4m2Q= Content-Type: application/http Content-ID: <response-b29c5de2-0db4-490b-b421-6a51b598bd22+1> HTTP/1.1 200 OK ETag: "lGaP-E0memYDumK16YuUDM_6Gf0/V43j6azD55CPRGb9b6uytDYl61Y" Content-Type: application/json; charset=UTF-8 Date: Mon, 22 Jan 2018 18:56:00 GMT Expires: Mon, 22 Jan 2018 18:56:00 GMT Cache-Control: private, max-age=0 Content-Length: 846 { "kind": "storage#object", "id": "example-bucket/obj1/1495822576643790", . . . "metadata": { "type": "tabby" }, . . . } --batch_pK7JBAk73-E=_AA5eFwv4m2Q= Content-Type: application/http Content-ID: <response-b29c5de2-0db4-490b-b421-6a51b598bd22+2> HTTP/1.1 200 OK ETag: "lGaP-E0memYDumK16YuUDM_6Gf0/91POdd-sxSAkJnS8Dm7wMxBSDKk" Content-Type: application/json; charset=UTF-8 Date: Mon, 22 Jan 2018 18:56:00 GMT Expires: Mon, 22 Jan 2018 18:56:00 GMT Cache-Control: private, max-age=0 Content-Length: 846 { "kind": "storage#object", "id": "example-bucket/obj2/1495822576643790", . . . "metadata": { "type": "tuxedo" }, . . . } --batch_pK7JBAk73-E=_AA5eFwv4m2Q= Content-Type: application/http Content-ID: <response-b29c5de2-0db4-490b-b421-6a51b598bd22+3> HTTP/1.1 200 OK ETag: "lGaP-E0memYDumK16YuUDM_6Gf0/d2Z1F1_ZVbB1dC0YKM9rX5VAgIQ" Content-Type: application/json; charset=UTF-8 Date: Mon, 22 Jan 2018 18:56:00 GMT Expires: Mon, 22 Jan 2018 18:56:00 GMT Cache-Control: private, max-age=0 Content-Length: 846 { "kind": "storage#object", "id": "example-bucket/obj3/1495822576643790", . . . "metadata": { "type": "calico" }, . . . } --batch_pK7JBAk73-E=_AA5eFwv4m2Q=--
如果整体请求格式设置不正确,并且 Cloud Storage 无法解析为子请求,您会收到 400
错误。否则,即使部分或全部子请求失败,Cloud Storage 也会返回 200
状态代码。
如果整体请求返回 200
状态代码,则响应会包含每个子请求的结果,包括针对各子请求的状态码,指示子请求是成功还是失败。例如,在批量删除对象时,每个成功的子请求都包含 204 No Content
状态代码。