跳转到: 导航, 搜索

Zaqar/specs/api/v1

Marconi API: v1 蓝图

Marconi v1 API 已冻结

我们已经开始收集反馈,以便对 API 进行扩展和 v2 版本,请参见:Marconi/specs/api/next


概述

Marconi 提供基于 HTTP 的 API,其风格类似于 REST 架构风格

本指南假定读者熟悉 REST、HTTP/1.1 和 JSON。URI 模板使用与 RFC 6570 相同的语法。

注意:错误响应在单独的页面上列出:Marconi/specs/api/v1/errors


通用 API 元素

客户端

  • 客户端应遵循 HTTP 重定向
  • 客户端应声明 gzip 支持
  • 客户端必须在 UserAgent 请求头中标识自身;例如,“User-Agent: python/2.7 cloudthing/1.2”
  • 客户端不得硬编码 URI 路径或模板,因为它们可能会随着时间的推移而更改。相反,客户端应缓存 API 提供的链接和链接模板。


API 版本控制

Marconi API 使用 URI 版本控制方案。路径的第一个元素包含目标版本标识符,例如:

  https://marconi.example.com/v1

URI 版本仅会在适应主要新功能或无法向后兼容的 API 重新设计时增加。发布新的 API 版本时,旧版本将被弃用。Marconi 维护者将与开发人员和合作伙伴合作,以确保在弃用旧版本之前有足够的时间迁移到新版本。

由于版本仅在适应主要 API 修订时增加,因此 API 的子版本很少见,但偶尔可能会用于发布“完善”的主要版本。

资源媒体类型

API 支持 `application/json`(XML 正在规划中),编码为 UTF-8。服务器可选地支持 gzip 编码的请求。

应忽略未识别的协议元素。这包括 XML 元素和属性、JSON 对象属性、链接关系类型、媒体类型等。


身份验证

可以由中间件或反向代理实现。如果实现,则适用以下内容

所有对 API 的请求只能由经过身份验证的代理执行。

为了进行身份验证,代理向 Keystone Identity Service 端点发出身份验证请求。

响应于有效的凭据,Keystone 响应一个身份验证令牌和一个服务目录,其中包含为给定令牌可用的所有服务和端点的列表。根据物理位置以及不同部署的性能/可用性特征,可以为 Marconi 返回多个端点。

通常,Keystone 中间件会根据 Marconi 客户端提交的身份验证令牌提供 X-Project-Id 头部。为了使之工作,客户端必须在每个对 Marconi API 的请求中指定有效的身份验证令牌。API 在服务每个请求之前,都会针对 Keystone 验证身份验证令牌。

如果未启用身份验证,客户端必须自行提供 X-Project-Id 头部。

授权

可以由中间件或反向代理实现。如果实现,则适用以下内容

API 需要根据提供的身份验证令牌(RBAC)验证对所有端点的读/写访问权限。ACL 应与令牌一起缓存。


端点

客户端可以选择与从 Keystone 检索到的任何服务端点进行交互。代理使用给定的端点作为主文档 href,从中发现所有其他 API 请求的链接。端点可以按区域组织

一个示例端点

https://marconi.example.com/v1

错误

如果任何请求导致错误,服务器将返回适当的 4xx 或 5xx HTTP 状态代码,并可选地在主体中返回以下信息

  • 标题
  • 描述
  • 内部代码
  • 更多信息的链接


示例

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "title": "Unsupported limit",
  "description": "The given limit cannot be negative, and cannot be greater than 50.",
  "code": 1092,
  "link": {
    "rel": "help",
    "href": "http://docs.example.com/messages#limit",
    "text": "API documentation for the limit parameter"
  }
}

通用头部

对 API 的每个请求都必须包含某些标准和扩展的 HTTP 头部。这些头部向服务器提供主机、代理、身份验证和其他相关信息。

头部 描述
Host API 的主机名,如 Keystone 服务目录中所引用
日期 当前日期和时间,使用标准的 RFC 1123 HTTP 日期格式
Accept 所需的媒体类型;目前仅支持 application/json
Accept-Encoding 指定代理接受 gzip 编码的响应主体
Content-Length 对于 POST 或 PUT 请求,正在提交的消息文档的字节数
X-Auth-Token Keystone 身份验证令牌
X-Project-Id 一个项目 ID,X-Auth-Token 的值授予对其的访问权限。队列将在该项目下创建。
Client-ID 一个 UUID,用于区分使用该服务的每个客户端。必须以规范形式提交 UUID(例如,3381af92-2b9e-11e3-b191-71861300734c)。在 Marconi 中,这用于避免将发送者的消息回显到相同的实例,并且服务器可能会将其记录以供将来使用。应在客户端重启之间生成一次并持久化。

HTTP 响应代码

请参阅 响应代码

示例 API 请求

GET /v1/queues/fizbat/messages?marker=1355-237242-783&limit=10 HTTP/1.1
Host: marconi.example.com
User-Agent: python/2.7 killer-rabbit/1.2
Date: Wed, 28 Nov 2012 21:14:19 GMT
Accept: application/json
Accept-Encoding: gzip
X-Auth-Token: 7d2f63fd-4dcc-4752-8e9b-1d08f989cc00
X-Project-Id: 518b51ea133c4facadae42c328d6b77b
Client-ID: 30387f00-39a0-11e2-be4d-a8d15f34bae2

端点概要

# Base endpoints
GET /v1
GET /v1/health

# Queues
GET /v1/queues{?marker,limit,detailed}
GET /v1/queues/{queue_name}  # existence check
HEAD /v1/queues/{queue_name}  # existence check
PUT /v1/queues/{name}
DELETE /v1/queues/{name}

# Queue metadata
PUT /v1/queues/{queue_name}/metadata
GET /v1/queues/{queue_name}/metadata
GET /v1/queues/{queue_name}/stats

# Messages
GET /v1/queues/{queue_name}/messages{?marker,limit,echo,include_claimed}
GET /v1/queues/{queue_name}/messages/{message_id}
GET /v1/queues/{queue_name}/messages{?ids}
POST /v1/queues/{queue_name}/messages
DELETE /v1/queues/{queue_name}/messages/{message_id}{?claim_id}
DELETE /v1/queues/{queue_name}/messages{?ids}

# Claims
POST /v1/queues/{queue_name}/claims{?limit}
GET /v1/queues/{queue_name}/claims/{claim_id}
PATCH /v1/queues/{queue_name}/claims/{claim_id}
DELETE /v1/queues/{queue_name}/claims/{claim_id}

基本端点

获取主文档

模板

GET /v1


请求

GET /v1 HTTP/1.1
Host: marconi.example.com

...


响应

HTTP/1.0 200 OK

...

{
    "resources": {
        "rel/queue-stats": {
            "href-template": "/v1/queues/{queue_name}/stats", 
            "href-vars": {
                "queue_name": "param/queue_name"
            }, 
            "hints": {
                "allow": [
                    "GET"
                ], 
                "formats": {
                    "application/json": {}
                }
            }
        }, 
        "rel/post-messages": {
            "href-template": "/v1/queues/{queue_name}/messages", 
            "href-vars": {
                "queue_name": "param/queue_name"
            }, 
            "hints": {
                "accept-post": [
                    "application/json"
                ], 
                "allow": [
                    "POST"
                ], 
                "formats": {
                    "application/json": {}
                }
            }
        }, 
        "rel/queue": {
            "href-template": "/v1/queues/{queue_name}", 
            "href-vars": {
                "queue_name": "param/queue_name"
            }, 
            "hints": {
                "allow": [
                    "GET", 
                    "HEAD", 
                    "PUT", 
                    "DELETE"
                ], 
                "formats": {
                    "application/json": {}
                }
            }
        }, 
        "rel/queue-metadata": {
            "href-template": "/v1/queues/{queue_name}/metadata", 
            "href-vars": {
                "queue_name": "param/queue_name"
            }, 
            "hints": {
                "allow": [
                    "GET", 
                    "PUT"
                ], 
                "formats": {
                    "application/json": {}
                }
            }
        }, 
        "rel/queues": {
            "href-template": "/v1/queues{?marker,limit,detailed}", 
            "href-vars": {
                "marker": "param/marker", 
                "detailed": "param/detailed", 
                "limit": "param/queue_limit"
            }, 
            "hints": {
                "allow": [
                    "GET"
                ], 
                "formats": {
                    "application/json": {}
                }
            }
        }, 
        "rel/messages": {
            "href-template": "/v1/queues/{queue_name}/messages{?marker,limit,echo,include_claimed}", 
            "href-vars": {
                "marker": "param/marker", 
                "include_claimed": "param/include_claimed", 
                "queue_name": "param/queue_name", 
                "limit": "param/messages_limit", 
                "echo": "param/echo"
            }, 
            "hints": {
                "allow": [
                    "GET"
                ], 
                "formats": {
                    "application/json": {}
                }
            }
        }, 
        "rel/claim": {
            "href-template": "/v1/queues/{queue_name}/claims{?limit}", 
            "href-vars": {
                "queue_name": "param/queue_name", 
                "limit": "param/claim_limit"
            }, 
            "hints": {
                "accept-post": [
                    "application/json"
                ], 
                "allow": [
                    "POST"
                ], 
                "formats": {
                    "application/json": {}
                }
            }
        }
    }
}


讨论

整个 Marconi API 都可以从一个起点发现;代理不需要知道超过此 URI 的任何信息才能探索整个 API。

此文档是可缓存的(应由代理和客户端缓存)。

另请参阅:http://tools.ietf.org/html/draft-nottingham-json-home-02

检查节点健康状况

模板

GET /v1/health

或者

HEAD /v1/health


请求

GET /v1/health HTTP/1.1
Host: example.marconi.com

...


响应

HTTP/1.1 204 No Content

或者

HTTP/1.1 503 Service Unavailable


讨论

使用此请求检查 Marconi 节点状态。如果节点关闭,此端点将不可访问,并作为负载均衡器从轮换中移除节点的信号。或者,端点可能可访问,但由于存储驱动程序故障或其他错误,服务暂时不可用。

队列

创建队列

模板

PUT /v1/queues/{queue_name}

请求

PUT /v1/queues/fizbat HTTP/1.1
Host: marconi.example.com


响应

HTTP/1.1 201 Created
Location: /v1/queues/fizbit


讨论

创建队列。

PUT 的主体为空。

queue_name 是要赋予队列的名称。名称长度不得超过 64 个字节,并且仅限于 US-ASCII 字母、数字、下划线和连字符。

列出队列

模板

GET /v1/queues{?marker,limit,detailed}


请求

GET /v1/queues?marker=baz&detailed=true HTTP/1.1
Host: marconi.example.com

...


响应

HTTP/1.1 200 OK

{
  "links": [
    {
      "rel": "next",
      "href": "/v1/queues?marker=kooleo&limit=10&detailed=true"
    }
  ],
  "queues": [
    { "name": "boomerang", "href": "/v1/queues/boomerang", "metadata": {} },
    { "name": "fizbit", "href": "/v1/queues/fizbit", "metadata": { "handle": "@kgriffs" } },

    ...

    { "name": "kooleo",  "href": "/v1/queues/kooleo", "metadata": { "something": "something_else" } }
  ]
}

检查队列是否存在

模板

GET /v1/queues/{queue_name}


请求

GET /v1/queues/{queue_name}
Host: marconi.example.com


响应

HTTP/1.1 204 OK


讨论

如果队列存在,则返回 204,否则返回 404。

HEAD 也可以工作。

删除队列

模板

DELETE /v1/queues/{queue_name}


请求

DELETE /v1/queues/fizbat HTTP/1.1
Host: marconi.example.com


响应

HTTP/1.1 204 No Content


讨论

使用此操作立即删除队列及其所有消息(如果有)。

队列元数据

设置队列元数据

模板

PUT /v1/queues/{queue_name}/metadata

{
   ...
}


请求

PUT /v1/queues/fizbat/metadata HTTP/1.1
Host: marconi.example.com

...

{
   "key": {
       "key2": "value",
       "key3": [1, 2, 3, 4, 5]
    }
}


响应

HTTP/1.1 204 No Content


讨论

此操作允许设置结构化元数据。如果使用 PUT,则此文档将完全替换现有的元数据文档,因此客户端需要小心,以免意外删除字段。

请求的主体是一个任意文档,允许存储有关特定应用程序应如何与队列交互的上下文信息。此主体的字符数(包括空格)必须小于或等于 64 KiB(可配置)。该文档必须是有效的 JSON(Marconi 将进行验证)。

获取队列元数据

模板

GET /v1/queues/{queue_name}/metadata


请求

GET /v1/queues/fizbit/metadata HTTP/1.1
Host: marconi.example.com

...


响应 HTTP/1.1 200 OK

{
   "key": {
       "key2": "value",
       "key3": [1, 2, 3, 4, 5]
    }
}


讨论

返回队列元数据。

获取队列统计信息

模板

GET /v1/queues/{queue_name}/stats


请求

GET /v1/queues/fizbit/stats HTTP/1.1
Host: marconi.example.com

...


响应 HTTP/1.1 200 OK

{
  "messages": {
    "free": 146929,
    "claimed": 2409,
    "total": 149338,
    "oldest": {
        "href": "/v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01",
        "age": 63,
        "created": "2013-08-12T20:44:55Z"
    },
    "newest": {
        "href": "/v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01",
        "age": 12,
        "created": "2013-08-12T20:45:46Z"
    }
}


讨论

返回队列统计信息,包括队列中的消息数量,按状态细分。

注意:如果总数为 0,则不包含“最旧”和“最新”消息统计信息。

消息

所有消息相关操作都需要在头部包含 Client-Id。这是为了确保消息不会回显到发布它们的客户端,除非客户端明确请求这样做。

列出消息

模板

GET /v1/queues/{queue_name}/messages{?marker,limit,echo,include_claimed}


请求

GET /v1/queues/fizbit/messages?marker=1355-237242-783&limit=10 HTTP/1.1
Host: marconi.example.com

...


响应

HTTP 200 如果查询匹配 1 个或多个消息,否则 HTTP 204(没有主体)。

HTTP/1.1 200 OK
Content-Location: /v1/queues/fizbit/messages?marker=1355-237242-783&limit=10

...

{
  "links": [
    {
      "rel": "next",
      "href": "/v1/queues/fizbit/messages?marker=6244-244224-783&limit=10"
    }
  ],
  "messages": [
    {
      "href": "/v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01",
      "ttl": 800,
      "age": 790,
      "body": {
        "event": "ActivateAccount",
        "mode": "active"
      }
    }
  ]
}


讨论

消息 ID 和标记是不透明字符串;客户端不应假定它们的格式或长度。此外,客户端应假定标记和消息 ID 之间没有关系(即,一个不能从另一个推断出来)。这允许各种存储驱动程序实现。

结果按年龄排序,最旧的消息在前。

limit 指定要返回的消息数量最多为 20 个(可配置)。如果未指定,则限制默认为 10。当可用消息多于可以一次请求返回的消息时,客户端可以通过简单地在从上一个调用返回的 URI 模板参数中使用的“next”字段(TBD)来获取下一批。

marker 是一个不透明字符串,客户端可以使用它来请求下一批消息。它将客户端已接收的消息告知服务器。

注意:如果未指定 marker,API 将返回队列头部的所有消息(最多限制)。

echo 是一个布尔值(即“true”或“false”),用于确定 API 是否返回客户端自己的消息,由 Client-ID 头部的 uuid 部分确定。如果未指定,则 echo 默认为“false”。

include_claimed 是一个布尔值(即“true”或“false”),用于确定 API 是否返回已声明的消息以及未声明的消息。如果未指定,则默认为“false”(仅返回未声明的消息)。

获取特定消息

模板

GET /v1/queues/{queue_name}/messages/{message_id}


请求

GET /v1/queues/fizbat/messages/50b68a50d6f5b8c8a7c62b01 HTTP/1.1
Host: marconi.example.com

...


响应

HTTP/1.1 200 OK
Content-Location: /v1/queues/fizbat/messages/50b68a50d6f5b8c8a7c62b01

...

{
  "href": "/v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01",
  "ttl": 800,
  "age": 790,
  "body": {
    "event": "ActivateAccount",
    "mode": "active"
  }
}


讨论

消息字段定义如下

href 是一个不透明的相对 URI,客户端可以使用它来唯一标识消息资源并与其交互。

ttl 是在发布消息时设置的 ttl。消息将在 (ttl - age) 秒后过期。

age 相对于服务器时钟的 ts 以来的秒数。

body 提交的消息的任意文档。

如果消息 ID 或声明 ID 格式不正确或不存在,则不返回任何消息。

按 ID 获取一组消息

模板

GET /v1/queues/{queue_name}/messages{?ids}


请求

GET /v1/queues/fizbat/messages?ids=50b68a50d6f5b8c8a7c62b01,f5b8c8a7c62b0150b68a50d6 HTTP/1.1
Host: marconi.example.com

...


响应

HTTP/1.1 200 OK
Content-Location: /v1/queues/fizbat/messages?ids=50b68a50d6f5b8c8a7c62b01,f5b8c8a7c62b0150b68a50d6

...

[
    {
      "href": "/v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01",
      "ttl": 800,
      "age": 32,
      "body": {
        "cmd": "EncodeVideo",
        "jobid": 58229 
      }
    },
    {
      "href": "/v1/queues/fizbit/messages/f5b8c8a7c62b0150b68a50d6",
      "ttl": 800,
      "age": 790,
      "body": {
        "cmd": "EncodeAudio",
        "jobid": 58201 
      }
    }
]


讨论

与消息列表不同,在此方法中始终返回客户端自己的消息。ID 列表不得超过 20 个(可配置,与一次可以发布的消息数量的设置共享)。

此方法返回所有具有匹配 ID 的消息。如果提供格式不正确的 ID 或不存在的消息 ID,则将其忽略并返回其余消息。

发布消息

模板

POST /v1/queues/{queue_name}/messages


请求

POST /v1/queues/fizbit/messages HTTP/1.1
Host: marconi.example.com

...

[
  {
    "ttl": 300,
    "body": {
      "event": "BackupStarted",
      "backup_id": "c378813c-3f0b-11e2-ad92-7823d2b0f3ce"
    }
  },
  {
    "ttl": 60,
    "body": {
      "event": "BackupProgress",
      "current_bytes": "0",
      "total_bytes": "99614720"
    }
  }
]


响应

提交单个消息时

HTTP/1.1 201 Created
Location: /v1/queues/fizbit/messages?ids=50b68a50d6f5b8c8a7c62b01
Content-Type: application/json

{
    "resources": [
        "/v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01"
    ],
    "partial": false
}

提交多个消息时

HTTP/1.1 201 Created
Location: /v1/queues/fizbit/messages?ids=50b68a50d6f5b8c8a7c62b01,50b68a50d6f5b8c8a7c62b05
Content-Type: application/json

{
    "resources": [
        "/v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01",
        "/v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b05"
    ],
    "partial": false
}

讨论

可以一次提交最多 20 个消息(默认,但可配置),但必须始终封装在一个集合容器中(JSON 中的数组)。结果 Location 头部或响应主体中的值可用于检索提交的消息以供进一步处理(如果需要)。

客户端仅指定消息的主体和 ttl;服务器将插入 ID 和年龄等元数据。

响应主体包含与请求中提交的每个消息对应的资源路径列表,顺序相同。如果服务器在处理提交的消息过程中出现错误,将返回部分列表,partial 将为 true,并且客户端需要重试发布剩余的消息。如果无法入队任何消息,服务器将返回 503 服务不可用。

NOTE: The partial field has been deprecated since the icehouse release, and will always be "false"; drivers are not longer allowed to return a "partial" success and so must either succeed or fail the entire batch of messages.

请求文档的大小(包括空格)默认为 256 KiB(可配置)。该文档必须是有效的 JSON(Marconi 将进行验证)。

body 指定要发送的消息的主体。

ttl 是服务器在消息过期并从队列中移除之前应该等待的时间。值必须在 60 到 1209600 秒(14 天,可配置)之间,包含边界值。请注意,服务器可能不会在消息达到 (ttl + 60) 秒时立即删除该消息,以便在存储实现方面提供灵活性。

删除消息

模板

DELETE /v1/queues/{queue_name}/messages/{message_id}{?claim_id}


请求

DELETE /v1/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01 HTTP/1.1
Host: marconi.example.com

...


响应

HTTP/1.1 204 No Content


讨论

message_id 指定要删除的消息。

claim_id 指定只有当消息具有指定的 claim ID 并且该 claim 未过期时,才应删除该消息。这对于确保只有一个 agent 处理任何给定的消息非常有用;每当 worker client 的 claim 在其有机会删除其已处理的消息之前过期时,worker 必须回滚基于该消息所采取的任何操作,因为另一个 worker 现在将能够 claim 并处理相同的消息。

请注意,如果未指定 claim_id,但消息已被 claim,则操作将失败。换句话说,已 claim 的消息只能通过提供适当的 claim_id 来删除。

按 ID 删除一组消息

模板

DELETE /v1/queues/{queue_name}/messages{?ids}


请求

DELETE /v1/queues/fizbit/messages?ids=50b68a50d6f5b8c8a7c62b01,50b68a50d6f5b8c8a7c62b02 HTTP/1.1
Host: marconi.example.com

...


响应

HTTP/1.1 204 No Content


讨论

批量删除消息。

ids 指定要删除的消息,最多 20 个(可配置,与发布和列出消息的设置相同)

如果任何消息 ID 格式不正确或不存在,则会被忽略。其余有效的消息 ID 将被删除。

声明

Claim 消息

模板

POST /v1/queues/{queue_name}/claims{?limit}
Content-Type: application/json

...

{ 
    "ttl": {claim_ttl},
    "grace": {message_grace}
}


请求

POST /v1/queues/fizbit/claims?limit=5 HTTP/1.1
Content-Type: application/json
Accept: application/json

...

{ 
    "ttl": 300,
    "grace": 300
}


响应

客户端接收一个 claim URI 和一个已 claim 消息的列表(如果有的话)

HTTP/1.1 201 Created
Content-Type: application/json
Location: /v1/queues/foo-bar/claims/a28ee94e-6cb4-11e2-b4d5-7703267a7926

...

[
  {
    "href": "/v1/queues/foo-bar/messages/50b68a50d6f5b8c8a7c62b01?claim_id=a28ee94e-6cb4-11e2-b4d5-7703267a7926",
    "ttl": 800,
    "age": 100,
    "body": {
      "object_id": "8a50d6",
      "target": "h.264"
    }
  },
  {
    "href": "/v1/queues/foo-bar/messages/50b68a50d6f5b8c8a7c62b02?claim_id=a28ee94e-6cb4-11e2-b4d5-7703267a7926",
    "ttl": 800,
    "age": 790,
    "body": {
      "object_id": "fb8c8a",
      "target": "h.264"
    }
  }
]


讨论

Claim 一组消息,最多达到限制,从最旧到最新,跳过任何已 claim 的消息。如果没有可用的未 claim 消息,则返回 204 No Content。

客户端应在完成消息处理后,在 claim 过期之前删除该消息,以确保消息仅处理一次。作为删除操作的一部分,所有 worker client 都应指定 claim ID(最好是通过简单地使用提供的 href 来完成)。这样,服务器就可以在 claim 刚刚过期时返回错误(通知客户端存在竞争条件),从而使 worker 有机会回滚其对给定消息的处理,因为另一个 worker 可能会 claim 并处理该消息。

与消息的年龄一样,claim 的年龄也是相对于服务器时钟而言的,对于确定消息的处理速度以及给定消息的 claim 是否即将过期非常有用。

当 claim 过期时,它将被移除,允许另一个客户端 worker 在原始 worker 无法处理它时 claim 该消息。

limit 指定要 claim 的最多 20 条消息(可配置)。如果未指定,则 limit 默认为 10。请注意,claim 创建是尽力而为的,这意味着服务器可能会 claim 并返回少于请求数量的消息。

ttl 是服务器在释放 claim 之前应该等待的时间。值必须在 60 到 43200 秒(12 小时,可配置)之间。

grace 是消息的宽限期,以秒为单位。值必须在 60 到 43200 秒(12 小时,可配置)之间。服务器将延长已 claim 消息的生命周期,使其至少与 claim 本身的生命周期一样长,再加上指定的宽限期,以处理崩溃的 worker(最多 1209600 或 14 天,包括 claim 生命周期)。如果已 claim 的消息通常会比宽限期更长,则其过期时间将不会被调整。

查询 Claim

模板

GET /v1/queues/{queue_name}/claims/{claim_id}


请求

GET /v1/queues/foo-bar/claims/a28ee94e-6cb4-11e2-b4d5-7703267a7926
Host: marconi.example.com

...


响应

HTTP/1.1 200 OK
Content-Location: /v1/queues/foo-bar/claims/a28ee94e-6cb4-11e2-b4d5-7703267a7926

...

{
  "age": 19,
  "ttl": 30,
  "messages": [
    ...
  ]
}


讨论

更新 Claim

模板

PATCH /v1/queues/{queue_name}/claims/{claim_id}
Content-Type: application/json


请求

PATCH /v1/queues/fizbit/claims/a28ee94e-6cb4-11e2-b4d5-7703267a7926 HTTP/1.1
Content-Type: application/json

...

{ "ttl": 300 }


响应

HTTP/1.1 204 No Content


讨论

客户端应在长时间运行的批量作业期间定期更新 claim,以避免在处理消息过程中丢失 claim。这通过向特定的 claim 资源发出 PATCH 请求并包含 claim 的新 TTL(可能与原始 TTL 不同)来完成。服务器将重置 claim 的年龄并应用新的 TTL。

释放 Claim

模板

DELETE /v1/queues/{queue_name}/claims/{claim_id}


请求

DELETE /v1/queues/foo-bar/claims/a28ee94e-6cb4-11e2-b4d5-7703267a7926 HTTP/1.1
Host: marconi.example.com


响应

HTTP/1.1 204 No Content


讨论

使用此操作立即释放 claim,使与该 claim 关联的任何(剩余的、未删除的)消息可供其他 worker 使用。

当 worker 执行优雅关闭、无法处理一个或多个消息,或者处理消息花费的时间比预期更长,并且希望使剩余消息可供其他 worker 使用时,此操作很有用。