拆分流量

您可以使用流量拆分来指定服务中两个或多个版本之间的流量分配比例。通过拆分流量,您可以在版本之间进行 A/B 测试,并控制功能的推广速度。

流量拆分适用于未明确指向某个版本的网址。例如,以下网址之所以能够拆分流量,是因为它们指向指定服务中的所有可用版本:

  • [MY_PROJECT].appspot.com - 将流量分配给 default 服务的各版本。
  • [MY_SERVICE].[MY_PROJECT].appspot.com - 将流量分配给 [MY_SERVICE] 服务的各版本。

如需了解请求到达版本的方式,请参阅请求的路由方式

准备工作

您需要确保您的用户帐号包含所需的权限,然后才能将流量配置到某个版本。

避免缓存问题

在启用流量拆分之前,您可能需要考虑潜在的缓存问题。任何 App Engine 应用都可能出现缓存问题,尤其是在部署新版本时。流量拆分通常会凸显不易发觉的缓存问题。

例如,假设您在 A 和 B 两个版本之间拆分流量,并且两个版本中的某个外部可缓存资源(例如 CSS 文件)发生了改变。现在假设客户端发出了一个请求,并且响应包含对缓存文件的外部引用。无论缓存了哪个版本的文件以及哪个版本的应用发送了响应,只要文件在缓存中,本地 HTTP 缓存都将检索该文件。缓存的资源可能与响应中发送的数据不兼容。

要规避缓存问题,请执行以下操作:

  • 对于动态资源,请同时设置 Cache-ControlExpires 标头。这些标头会告知代理资源是动态的。最好同时设置这两个标头,因为并非所有代理服务器都能正确支持 HTTP/1.1 Cache-Control 标头。

    如需大致了解有关缓存的更多信息,请参阅 HTTP/1.1 RFC 中的标头字段浏览器安全手册中的文档缓存

  • 对于因版本而异的可缓存静态资源,请在各版本之间更改资源的网址。如果从不同的网址提供静态资源,那么这两个版本可以在代理服务器和浏览器缓存中和谐共存。

您还可以让应用设置 Vary: Cookie 标头,以便通过组合相应请求的 Cookie 和网址来计算资源的唯一性。但是,这种方法会增加缓存服务器的负担。GOOGAPPUID 有 1000 个可能的值,因此应用的每个网址有 1000 个可能的条目。根据用户与应用之间的代理的负载情况,这可能会降低缓存命中率。另请注意,在将新批次用户添加到某个版本后的 24 小时内,他们可能仍会看到缓存的资源。但是,通过使用 Vary: Cookie,您可以更轻松地重命名不同版本中变动的静态资源。

使用 Vary: Cookie 的技巧并不适用于所有情况。通常,如果您的应用将 Cookie 用于其他用途,则必须考虑这对代理服务器的负担有何影响。如果 codeninja 有自己的 Cookie,其中包含 100 个可能的值,那么所有可能的缓存条目的空间将变得非常庞大(100 * 1000 = 100,000)。在最糟糕的情况下,每个用户都有一个唯一的 Cookie。这种情况的两个常见示例是 Google Analytics(分析)(__utma) 和 SiteCatalyst (s_vi)。在此类情况下,每个用户都会获得一个唯一的副本,这不仅会严重降低缓存性能,还会增加应用消耗的计费实例小时。

将流量拆分至多个版本

如果已指定在两个或更多个版本之间拆分流量,则必须选择是使用 IP 地址还是使用 HTTP Cookie 进行拆分。设置 IP 地址拆分更容易,但 Cookie 拆分更精确。如需了解详情,请参阅 IP 地址拆分Cookie 拆分

Console

要在 GCP Console 中拆分流量,请转到“版本”页面:

转到“版本”页面

  1. 选择流量要拆分到的一个或多个版本。
  2. 点击拆分流量,然后指定:
    • 要用于拆分流量的方法。
    • 每个版本应该收到的流量百分比。

gcloud

安装 Google Cloud SDK 后,请运行以下命令将流量拆分到多个版本,例如:

gcloud app services set-traffic [MY_SERVICE] --splits [MY_VERSION1]=[VERSION1_WEIGHT],[MY_VERSION2]=[VERSION2_WEIGHT] --split-by [IP_OR_COOKIE]

如需了解详情并获取其他选项,请参阅 gcloud app services set-traffic 参考。

API

要以编程方式迁移流量,您可以使用 Admin API。如需了解详情,请参阅迁移和拆分流量

IP 地址拆分

如果您选择按 IP 地址拆分应用流量,当该应用收到请求时,它会将 IP 地址哈希处理为介于 0-999 之间的值,并使用该数字来路由请求。

IP 地址拆分具有很大的局限性:

  • IP 地址比较固定,但不永久。通过手机连接的用户在单次会话期间使用的 IP 地址可能会不断变化。同样,使用笔记本电脑的用户可能会从家中前往咖啡馆办公,他们的 IP 地址也会发生变化。因此,当用户的 IP 地址发生变化时,他们使用应用的体验可能会不一致。
  • 由于 IP 地址单独分配给版本,因此产生的流量拆分会与您指定的流量拆分有所不同。不过,您的应用收到的流量越多,实际拆分也就越接近目标。例如,如果您要求将 5% 的流量传递给备用版本,则该版本收到的初始流量百分比实际上可能在 3-7% 之间,但最终的平均值会更接近 5% 这一目标。
  • 如果您需要在应用之间发送内部请求,则应改用 Cookie 拆分。在运行于 Google 云端基础架构上的应用之间发送的请求,源自可能全部分配给同一版本的少量 IP 地址。因此,所有内部请求的行为可能与从单个 IP 地址发送的请求类似,这意味着这些请求都将路由到同一版本。因此,内部请求不会严格遵循您为基于 IP 的流量拆分设置的百分比。例如,如果您将某个版本设置为接收应用总流量的 1%,并且 Google 云端基础架构地址恰好分配给该版本,则实际结果可能远远超过 1%,因为所有内部请求都始终路由到指定的版本。从 Google 云端基础架构外部发送到应用的请求将按预期工作,因为它们源自以不同方式分配的 IP 地址。

如果您选择按 Cookie 拆分应用流量,则应用会在 HTTP 请求标头中查找名为 GOOGAPPUID 的 Cookie,该 Cookie 中包含一个介于 0-999 之间的值:

  • 如果存在此 Cookie,则使用该值路由请求。
  • 如果没有此 Cookie,则会随机路由请求。

如果响应中不包含 GOOGAPPUID Cookie,则应用会先添加具有 0-999 之间的随机值的 GOOGAPPUID Cookie,然后再发送响应。

通过使用 Cookie 拆分流量,您可以更轻松地将用户准确地分配到各种版本。流量路由的精确度可以达到拆分目标的 0.1%。不过,Cookie 拆分仍有以下局限性:

  • 如果您正在编写移动应用或运行桌面客户端,则需要管理 GOOGAPPUID Cookie。例如,使用 Set-Cookie 响应标头时,您必须存储此 Cookie 并将其加入到每个后续请求中。基于浏览器的应用已采用此方法来自动管理 Cookie。

  • 拆分内部请求需要额外的操作。对于从 Google 的云端基础架构中发送的所有用户请求,您都必须转发每次请求中的用户 Cookie。例如,对于从您的应用发送到其自身或其他应用的请求,您必须转发这些请求中的用户 Cookie。请注意,如果内部请求并非源自用户,则建议不要发送这些请求。

停用流量拆分

要停用流量拆分,请将所有流量迁移到单个版本

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
App Engine standard environment for Python 2