使用商业市场计量服务的 Azure 容器按流量计费
借助商业市场计量服务,可以创建按非标准单位收费的 Azure 容器产品/服务。 在将产品/服务发布到商业市场之前,可以定义计费维度,例如带宽、分片、日志文件、扫描、处理的电子邮件等。然后,客户会根据这些维度的消耗付费,应用程序通过 商业市场计量服务 API 通知Microsoft发生可计费事件。
按流量计费的先决条件
若要使 Azure 容器产品/服务使用按流量计费,必须首先查看 Azure 容器套餐计划中概述的许可选项,并确保有六种现有预定义计费模型之一无法满足的自定义计费需求。
然后,Azure 容器产品/服务可以与 商业市场计量服务 API 集成,以通知Microsoft计费事件。
重要
应用程序必须调用商业市场计量服务 API。 目前没有允许托管服务(应用程序外部)调用计量服务 API 的选项。
注意
市场计量服务仅适用于自定义计费模型,不适用于每个用户的计费模型。
按流量计费如何定价
了解产品/服务层次结构对于定义产品/服务及其定价模型非常重要。
- 每个产品/服务都配置为通过Microsoft销售。 发布产品/服务后,无法更改此选项。
- 配置为通过Microsoft销售的每个产品/服务可以有一个或多个计划。
- 每个计划都有一个与之关联的定价模型:基于使用情况的按月计费计划或自带许可证(BYOL)。 对于基于使用情况的每月计费计划,可以选择免费、六个预定义计费选项之一或自定义。
- 发布后,无法更新定价模型和价格输入选项。
- 每个计划必须具有完整的定价计划。
- 可以选择使用自定义维度对客户收费,以帮助满足计费需求。 每个维度都表示服务使用商业市场计量服务 API 与Microsoft通信的计费单位。
重要
必须跟踪代码中的使用情况,并且仅将使用情况事件发送到Microsoft,以便对客户开具发票的使用情况。
注意
将使用创建套餐时发布的当地市场价格,以客户协议货币向客户收取套餐费用。 客户支付的金额以及 ISV 收到的金额取决于客户进行套餐交易时的外汇汇率。 详细了解“我们如何换算货币?”。
自定义定价选项示例
例如,Contoso 是一个发布者,其 IP 位于其 Kubernetes 应用程序的分片逻辑中。 Contoso 希望根据使用的分片数为其客户收费。 他们还正在探索其他方便且具有竞争力的计费选项。 Contoso 在商业市场计划的合作伙伴中心注册为发布者,并希望将容器产品/服务发布到 Azure 客户。 下面概述了四个与 Contoso 关联的计划:
按每小时使用的分片收费,例如 1,000 美元/分片/小时
对一次性付款或定期计费进行建模:假设 Contoso 希望向客户收取 449 美元/mo 的费用,以便从其应用程序中使用多达 100 个日志文件。 Contoso 的应用程序逻辑跟踪月份的使用事件,并在 100 个日志文件使用情况的月末触发费用。
建模分层计费:假设 Contoso 想要为高达 100 个分片收取 449 美元/mo 的费用,然后对任何超额进行分层定价。 其应用程序逻辑将跟踪月份的使用情况,相应地细分使用情况,并在期末使用以下计量 API 报告使用情况:
多维计费:Contoso 还可以使用自定义计量来满足使用多个维度的高级计费需求
根据所选计划,获取 Contoso 容器套餐的 Azure 客户会根据其使用情况收费。 Contoso 将使用情况计数,而不向Microsoft发送任何使用事件。 当客户消耗足够的量或定期使用时,Contoso 会报告使用情况。 客户无需更改计划或执行任何不同操作。 Contoso 测量使用情况并开始发出使用事件以Microsoft,以使用 商业市场计量服务 API 向超额使用量收费。 Microsoft又对客户收取自定义维度中发布者指定的使用情况费用。 计费是在下个月计费周期完成的。
计费维度
每个计费维度都定义了自定义单位,ISV 可以使用该单位发出使用量事件。 计费维度还用于向客户传达有关使用软件的计费方式。 它们的定义如下:
- ID:发送使用量事件时引用的不可变维度标识符。
- 显示名称:与维度关联的显示名称,例如“已发送文本消息”。
- 度量单位:计费单位的说明,例如“每条文本消息”或“每 100 封电子邮件”。
- 每单位的价格(以美元为单位):一个维度单位的价格。 它可以是 0。
重要
必须跟踪应用程序代码中的使用情况,并根据计费需求将使用情况事件发送到Microsoft。
一个产品/服务的所有计划共享计费维度。 某些属性适用于所有计划的维度,其他属性则特定于计划。
定义维度本身的属性则共享于一个产品/服务的所有计划。 发布产品/服务之前,从任何计划的上下文对这些属性所做的更改会影响所有计划的维度定义。 发布产品/服务后,这些属性将不再可编辑。 这些属性包括:
- ID
- 显示名称
- 度量单位
维度的其他属性特定于每个计划,且不同的计划可以有不同的值。 发布计划之前,可以编辑这些值,并且只会影响此计划。 发布计划后,将无法再编辑这些属性。 这些属性包括:
- 单位价格(美元)
维度还有一个名为“enabled”的特殊概念:
- 已启用 - 指示此计划使用此维度。 如果要创建不基于此维度发送使用情况事件的新计划,则可能需要取消选中此选项。 此外,在首次发布计划后添加的任何新维度在已发布的计划中都将显示为“未启用”。 已禁用的维度不会显示在客户看到的计划的任何维度列表中。
注意
显式支持以下方案:
- 可以将新维度添加到新计划。 对于任何已发布的计划,将不启用新维度。
根据支持的市场设置每个单位的维度价格
与其他基于使用情况的定价一样,可以根据受支持的国家或地区设置计费维度价格。 你需要使用合作伙伴中心的定价数据导入和导出功能,如下所示。
- 定义所需维度并标记支持的市场。
- 将此数据导出到文件中。
- 为每个国家/地区添加正确的价格,并在合作伙伴中心内导入该文件。
计量的用户界面会发生变化,以反映维度的价格只能在文件中看到。
专用计划
与预定义的基于使用情况的计费计划一样,具有自定义维度的计划可以设置为专用计划,只能由计划定义的受众访问。
约束
锁定行为
由于与商业市场计量服务配合使用的维度表示了解客户将如何为服务付费,因此在发布产品/服务后,将无法再编辑维度的所有详细信息。 在发布产品/服务之前,请务必为该计划完整定义维度。
使用维度发布产品/服务后,将无法再更改该维度的产品/服务级别的详细信息:
- ID
- 显示名称
- 度量单位
发布计划后,无法再更改此计划级详细信息:
- 是否为此计划启用此维度
上限
单个产品/服务可配置的最大维度数量为 30 个唯一维度。
Azure 容器按流量计费
当发布者为要在合作伙伴中心发布的产品/服务创建自定义计量维度时,应使用按流量计费 API。 如果购买的任何产品/服务具有一项或多项计划包含用于发出使用事件的自定义维度,则需要与按流量计费 API 集成。
重要
有关为 Kubernetes 应用创建自定义计量维度的详细信息,请参阅 “创建 Azure 容器产品/服务”。
强制实施 TLS 1.2 注释
我们强制要求使用 TLS 1.2 版本作为 HTTPS 通信的最低版本。 请确保在代码中使用此 TLS 版本。 TLS 版本 1.0 和 1.1 已弃用,并且拒绝连接尝试。
按流量计费的单一使用事件
发布者应调用使用事件 API,以针对为特定客户所购计划(订阅的)活动资源发出使用事件。 发布产品/服务时,将为发布者定义的计划的每个自定义维度分别发出使用事件。
在一个日历日中,针对每个资源和维度每小时只可发出一个使用事件。 如果在一小时内使用了多个单位,则累积该小时内使用的所有单位,然后在一个事件中将其发出。 只能发出最近 24 小时内的使用事件。 如果在 8:00 到 8:59:59(已接受)之间发出使用事件,并在 8:00 到 8:59:59 之间发送另一个事件,则会将其拒绝为重复项。
POST: https://marketplaceapi.microsoft.com/api/usageEvent?api-version=<ApiVersion>
查询参数:
参数 | 建议 |
---|---|
ApiVersion |
使用 2018-08-31。 |
请求标头:
Content-type | 使用 application/json |
---|---|
x-ms-requestid |
用于跟踪来自客户端的请求的唯一字符串值,最好是 GUID。 如果未提供此值,则会在响应标头中生成并提供一个值。 |
x-ms-correlationid |
客户端上的操作的唯一字符串值。 此参数将来自客户端操作的所有事件与服务器端的事件关联起来。 如果未提供此值,则会在响应标头中生成并提供一个值。 |
authorization |
唯一的访问令牌,用于标识发出此 API 调用的 ISV。 格式是在"Bearer <access_token>" 发布者检索令牌值时,如身份验证策略中的 Kubernetes 应用程序中所述。 |
请求正文示例:
{
"resourceUri": "<ARM resource URI of the Kubernetes app instance>", // unique identifier of the resource against which usage is emitted.
"quantity": 5.0, // how many units were consumed for the date and hour specified in effectiveStartTime, must be greater than 0 or a double integer
"dimension": "dim1", // custom dimension identifier
"effectiveStartTime": "2018-12-01T08:30:14", // time in UTC when the usage event occurred, from now and until 24 hours back
"planId": "plan1", // id of the plan purchased for the offer
}
注意
对于 Kubernetes 应用, resourceUri
它是 Kubernetes 应用实例的 ARM 资源 URI。
响应
代码:200
没问题。 Microsoft 端已接受并记录发出的使用情况,供进一步处理和计费。
响应有效负载示例:
{
"usageEventId": <guid>, // unique identifier associated with the usage event in Microsoft records
"status": "Accepted" // this is the only value in case of single usage event
"messageTime": "2020-01-12T13:19:35.3458658Z", // time in UTC this event was accepted
"resourceUri": "<ARM resource URI of the Kubernetes app instance>", // unique identifier of the resource against which usage is emitted. For SaaS it's the subscriptionId.
"quantity": 5.0, // amount of emitted units as recorded by Microsoft
"dimension": "dim1", // custom dimension identifier
"effectiveStartTime": "2018-12-01T08:30:14", // time in UTC when the usage event occurred, as sent by the ISV
"planId": "plan1", // id of the plan purchased for the offer
}
代码:400
请求错误。
- 未提供请求数据或提供了无效数据。
effectiveStartTime
是在 24 小时前。 事件已过期。
响应有效负载示例:
{
"message": "One or more errors have occurred.",
"target": "usageEventRequest",
"details": [
{
"message": "The resourceUri is required.",
"target": "ResourceUri",
"code": "BadArgument"
}
],
"code": "BadArgument"
}
代码:400
请求错误。
- 资源 URI 以前已注册,需要等待 24 小时才能提交使用情况。
响应有效负载示例:
{
"message": "One or more errors have occurred.",
"target": "usageEventRequest",
"details": [
{
"message": "Invalid usage state.",
"target": "ResourceUri",
"code": "BadArgument"
}
],
"code": "BadArgument"
}
代码:403
已禁止。 未提供授权令牌,令牌无效或已过期。
代码:409
冲突。 已成功报告了指定资源 ID、有效使用日期和时间的使用事件。
响应有效负载示例:
{
"additionalInfo": {
"acceptedMessage": {
"usageEventId": "<guid>", //unique identifier associated with the usage event in Microsoft records
"status": "Duplicate",
"messageTime": "2020-01-12T13:19:35.3458658Z",
"resourceUri": "<ARM resource URI of the Kubernetes app instance>", //unique identifier of the resource against which usage is emitted.
"quantity": 1.0,
"dimension": "dim1",
"effectiveStartTime": "2020-01-12T11:03:28.14Z",
"planId": "plan1"
}
},
"message": "This usage event already exist.",
"code": "Conflict"
}
按流量计费的批量使用事件
通过批量使用事件 API,可一次性发出多项已购资源的使用事件。 它还允许你为同一资源发出多个使用事件,前提是它们适用于不同的日历小时数。 一个批次中的最大事件数为 25。
POST: https://marketplaceapi.microsoft.com/api/batchUsageEvent?api-version=<ApiVersion>
查询参数:
参数 | 建议 |
---|---|
ApiVersion |
使用 2018-08-31。 |
请求标头:
Content-type | 使用 application/json |
---|---|
x-ms-requestid |
用于跟踪来自客户端的请求的唯一字符串值,最好是 GUID。 如果未提供此值,则会生成一个值,并在响应标头中提供该值。 |
x-ms-correlationid |
客户端上的操作的唯一字符串值。 此参数将来自客户端操作的所有事件与服务器端的事件关联起来。 如果未提供此值,则会生成并在响应标头中提供。 |
authorization |
唯一的访问令牌,用于标识发出此 API 调用的 ISV。 格式是在Bearer <access_token> 发布者检索令牌值时,如身份验证策略中的 Kubernetes 应用程序中所述。 |
注意
在请求正文中,Kubernetes 应用的资源标识符为 resourceUri
。
Kubernetes 应用的请求正文示例:
{
"request": [ // list of usage events for the same or different resources of the publisher
{ // first event
"resourceUri": "<ARM resource URI of the Kubernetes app instance>", // Unique identifier of the resource against which usage is emitted.
"quantity": 5.0, // how many units were consumed for the date and hour specified in effectiveStartTime, must be greater than 0 or a double integer
"dimension": "dim1", //Custom dimension identifier
"effectiveStartTime": "2018-12-01T08:30:14",//Time in UTC when the usage event occurred, from now and until 24 hours back
"planId": "plan1", // id of the plan purchased for the offer
},
{ // next event
"resourceUri": "<ARM resource URI of the Kubernetes app instance>",
"quantity": 39.0,
"dimension": "email",
"effectiveStartTime": "2018-11-01T23:33:10
"planId": "gold", // id of the plan purchased for the offer
}
]
}
响应
代码:200
没问题。 Microsoft 端已接受并记录批量发出的使用情况,供进一步处理和计费。 返回的响应列表中包含该批次中每个事件的状态。 你应遍历响应有效负载,了解在批量事件中发送的各个使用事件的响应。
响应有效负载示例:
{
"count": 2, // number of records in the response
"result": [
{ // first response
"usageEventId": "<guid>", // unique identifier associated with the usage event in Microsoft records
"status": "Accepted" // see list of possible statuses below,
"messageTime": "2020-01-12T13:19:35.3458658Z", // Time in UTC this event was accepted by Microsoft,
"resourceUri": "<ARM resource URI of the Kubernetes app instance>", // unique identifier of the resource against which usage is emitted.
"quantity": 5.0, // amount of emitted units as recorded by Microsoft
"dimension": "dim1", // custom dimension identifier
"effectiveStartTime": "2018-12-01T08:30:14",// time in UTC when the usage event occurred, as sent by the ISV
"planId": "plan1", // id of the plan purchased for the offer
},
{ // second response
"status": "Duplicate",
"messageTime": "0001-01-01T00:00:00",
"error": {
"additionalInfo": {
"acceptedMessage": {
"usageEventId": "<guid>",
"status": "Duplicate",
"messageTime": "2020-01-12T13:19:35.3458658Z",
"resourceUri": "<ARM resource URI of the Kubernetes app instance>",
"quantity": 1.0,
"dimension": "email",
"effectiveStartTime": "2020-01-12T11:03:28.14Z",
"planId": "gold"
}
},
"message": "This usage event already exist.",
"code": "Conflict"
},
"resourceId": "<guid2>",
"quantity": 1.0,
"dimension": "email",
"effectiveStartTime": "2020-01-12T11:03:28.14Z",
"planId": "gold"
}
]
}
BatchUsageEvent
API 响应中引用状态代码的说明:
状态代码 | 说明 |
---|---|
Accepted |
已接受。 |
Expired |
使用已过期。 |
Duplicate |
提供了重复的使用情况。 |
Error |
错误代码。 |
ResourceNotFound |
提供的使用资源无效。 |
ResourceNotAuthorized |
你无权为此资源提供使用情况。 |
ResourceNotActive |
资源已挂起或从未激活。 |
InvalidDimension |
用于传递使用情况的维度对于此产品/服务或计划无效。 |
InvalidQuantity |
传递的数量小于或等于 0。 |
BadArgument |
缺少输入,或输入格式不正确。 |
代码:400
请求错误。 该批次中包含的使用事件超过 25 个。
代码:403
已禁止。 未提供授权令牌,令牌无效或已过期。
按流量计费检索使用情况事件
你可以调用使用情况事件 API 来获取使用情况事件的列表。 ISV 可以使用此 API 来查看在特定的可配置时间段内已发布的使用情况事件,以及在调用 API 时这些事件的状态。
GET:https://marketplaceapi.microsoft.com/api/usageEvents
查询参数:
参数 | 建议 |
---|---|
ApiVersion | 使用 2018-08-31。 |
usageStartDate | ISO8601 格式的日期/时间。 例如,2020-12-03T15:00 或 2020-12-03 |
UsageEndDate(可选) | ISO8601 格式的日期/时间。 默认值 = 当前日期 |
offerId(可选) | 默认值 = 所有可用项 |
planId(可选) | 默认值 = 所有可用项 |
dimension(可选) | 默认值 = 所有可用项 |
azureSubscriptionId(可选) | 默认值 = 所有可用项 |
reconStatus(可选) | 默认值 = 所有可用项 |
reconStatus 的可能值:
ReconStatus | 说明 |
---|---|
已提交 | 尚未由 PC Analytics 进行处理 |
已接受 | 已使用 PC Analytics 进行匹配 |
已拒绝 | 已在管道中被拒绝。 请联系 Microsoft 支持部门来调查原因。 |
不匹配 | MarketplaceAPI 和合作伙伴中心分析数量都是非零的,但不匹配 |
TestHeaders | 订阅随测试标头一起列出,因此不在 PC Analytics 中 |
DryRun | 已在 SessionMode=DryRun 的情况下提交,因此不在 PC 中 |
请求标头:
内容类型 | 使用 application/json |
---|---|
x-ms-requestid | 唯一字符串值(最好是 GUID),用于跟踪来自客户端的请求。 如果未提供此值,则会在响应标头中生成并提供一个值。 |
x-ms-correlationid | 客户端上的操作的唯一字符串值。 此参数将来自客户端操作的所有事件与服务器端的事件关联起来。 如果未提供此值,则会在响应标头中生成并提供一个值。 |
授权 | 唯一的访问令牌,用于标识发出此 API 调用的 ISV。 如果令牌值是由发布者检索的,则格式为 Bearer <access_token> 。- 身份验证策略中的 Kubernetes 应用程序 |
响应
响应有效负载示例:
已接受
[
{
"usageDate": "2020-11-30T00:00:00Z",
"usageResourceId": "11111111-2222-3333-4444-555555555555",
"dimension": "tokens",
"planId": "silver",
"planName": "Silver",
"offerId": "mycooloffer",
"offerName": "My Cool Offer",
"offerType": "SaaS",
"azureSubscriptionId": "12345678-9012-3456-7890-123456789012",
"reconStatus": "Accepted",
"submittedQuantity": 17.0,
"processedQuantity": 17.0,
"submittedCount": 17
}
]
已提交
[
{
"usageDate": "2020-11-30T00:00:00Z",
"usageResourceId": "11111111-2222-3333-4444-555555555555",
"dimension": "tokens",
"planId": "silver",
"planName": "",
"offerId": "mycooloffer",
"offerName": "",
"offerType": "SaaS",
"azureSubscriptionId": "12345678-9012-3456-7890-123456789012",
"reconStatus": "Submitted",
"submittedQuantity": 17.0,
"processedQuantity": 0.0,
"submittedCount": 17
}
]
失 配
[
{
"usageDate": "2020-11-30T00:00:00Z",
"usageResourceId": "11111111-2222-3333-4444-555555555555",
"dimension": "tokens",
"planId": "silver",
"planName": "Silver",
"offerId": "mycooloffer",
"offerName": "My Cool Offer",
"offerType": "SaaS",
"azureSubscriptionId": "12345678-9012-3456-7890-123456789012",
"reconStatus": "Mismatch",
"submittedQuantity": 17.0,
"processedQuantity": 16.0,
"submittedCount": 17
}
]
已拒绝
[
{
"usageDate": "2020-11-30T00:00:00Z",
"usageResourceId": "11111111-2222-3333-4444-555555555555",
"dimension": "tokens",
"planId": "silver",
"planName": "",
"offerId": "mycooloffer",
"offerName": "",
"offerType": "SaaS",
"azureSubscriptionId": "12345678-9012-3456-7890-123456789012",
"reconStatus": "Rejected",
"submittedQuantity": 17.0,
"processedQuantity": 0.0,
"submittedCount": 17
}
]
状态代码
代码:403 禁止。 未提供授权令牌,令牌无效或已过期。
开发和测试最佳做法
若要测试自定义计量排放,请实现与计量 API 的集成,为已发布的 Kubernetes 应用产品/服务创建一个计划,其中包含以每单位零价格定义的自定义维度。 然后将此产品/服务作为预览版发布,以便只有有限数量的用户能够访问和测试集成。
还可对现有的有效产品/服务使用专用计划,在测试期间只有有限数量的用户可访问该计划。
相关内容
- 要详细了解计量服务 API,请参阅市场计量服务 API 常见问题解答。
获取支持
如果遇到以下问题之一,你可以打开支持票证。
- 市场计量服务 API 的技术问题。
- 由于自身错误或 bug(例如错误的使用量事件)而需要升级的问题。
- 与按流量计费相关的任何其他问题。
若要了解发布者支持选项和使用 Microsoft 打开支持票证,请遵照合作伙伴中心商业市场计划的支持中的说明。