Python 3.8 现已正式发布。

实例的管理方式

实例是 App Engine 的基本组件,提供托管应用所需的所有资源。在任意时间点,您的应用都可能在一个或多个实例上运行,而请求将分散到正在运行的所有实例。每个实例都有一个安全层,确保不会发生意外的相互影响。

App Engine 可以在流量波动时自动创建和关停实例,您也可以指定运行的实例数,而不考虑流量。如需确定创建新实例的方式和时间,请为您的应用指定扩缩类型。

扩缩类型

App Engine 支持以下扩缩类型,这些类型用于控制创建实例的方式和时间:

  • 自动
  • 基本
  • 手动

您可以在应用的 app.yaml 中指定扩缩类型。

自动扩缩
自动扩缩会根据请求速率、响应延迟时间和其他应用指标来创建实例。您可以为其中的每个指标指定阈值,以及指定应始终保持运行的最小实例数。
基本扩缩
基本扩缩会在应用收到请求时创建实例。当应用变为空闲状态时,每个实例都将关停。基本扩缩非常适合间歇性工作或由用户活动驱动的工作。
手动扩缩
手动扩缩会指定无论负载水平如何都持续运行的实例数。这种类型支持复杂初始化等任务,以及持久依赖内存状态的应用。
下表比较了三种扩缩类型的性能特征:

功能 自动扩缩 基本扩缩 手动扩缩
请求超时 对于 HTTP 请求和任务队列任务,为 10 分钟如果您的应用未在此时间限制内返回请求,则 App Engine 会中断请求处理程序并发出错误以供代码处理。

对于旧版运行时(Java 8、PHP 5 和 Python 2):

  • Cron 作业的任务队列任务和请求的超时时间为 10 分钟。
  • 其他 HTTP 请求的超时时间为 1 分钟。
HTTP 请求和任务队列任务为 24 小时。如果您的应用未在此时间限制内返回请求,则 App Engine 会中断请求处理程序并发出错误以供代码处理。

基本扩缩的实例可以选择处理 /_ah/start 并执行程序或脚本数小时,而不返回 HTTP 响应代码。

与基本扩缩相同。
驻留 实例根据使用模式关停。 实例根据 idle_timeout 参数关停。如果某个实例在空闲时间超过 idle_timeout 后仍未收到请求,则系统会将该实例关停。 实例会保留在内存中,而状态会跨请求保留。重启实例时,日志中会显示 /_ah/stop 请求。如果存在注册的关停钩子,其在关停之前有 30 秒的时间完成运行。
启动和关停 实例在需要处理请求时创建,在空闲时自动关闭。 实例会在需要处理请求时创建,在空闲时自动关停(由 idle_timeout 配置参数决定)。手动停止的实例在被强制终止之前有 30 秒的时间来完成请求处理。 App Engine 以向 /_ah/start 发出空白 GET 请求的形式自动向实例发送启动请求。和基本扩缩一样,手动停止的实例在被强制终止之前有 30 秒的时间来完成请求处理。
实例可寻址性 实例是匿名的。 服务“s”的“v”版本“i”实例可通过以下网址寻址:https://i-dot-v-dot-s-dot-app_id.REGION_ID.r.appspot.com。如果您为自定义网域设置了通配符子网域映射,则还可以通过 https://s.domain.comhttps://i.s.domain.com 格式的网址,针对服务或其任何实例进行寻址。您可以安心地在每个实例中缓存状态,并可在后续请求中检索此状态。 与基本扩缩相同。
扩缩 App Engine 会根据处理量自动扩缩实例数。这种扩缩会将在配置文件中基于版本提供的 automatic_scaling 设置考虑在内。 通过在 basic_scaling 设置的 max_instances 参数中指定实例数上限来配置使用基本扩缩的服务。活跃实例数会随着处理量的变化而变化。 您可以在该服务的配置文件中配置每个版本的实例数。实例数通常与内存中的数据集大小或所需的离线工作吞吐量相对应。

扩缩动态实例

使用基本扩缩或自动扩缩的 App Engine 应用可在给定时间由任意数量的动态实例提供支持,具体取决于传入请求的数量。随着对应用请求的增加,动态实例的数量可能也会增加。

使用基本扩缩的应用

如果使用基本扩缩,App Engine 会尝试保持低成本,即使随着传入请求量的增加,可能会导致更高的延迟。

当没有任何现有实例可用于处理传入请求时,App Engine 会启动一个新实例。即使在启动新实例后,某些请求可能需要排入队列,直到新实例完成其启动过程。如果需要尽可能减少延迟时间,请考虑使用自动扩缩,它会预先创建新实例以尽量减少延迟时间。

使用自动扩缩的应用

如果使用自动扩缩,则应用中的每个实例都有自己的传入请求队列。在队列变得足够长,对应用的延迟时间造成显著影响之前,App Engine 会自动创建一个或多个新实例来处理不断增加的负载。

您可以配置自动扩缩的设置,以便在理想性能与可能产生的费用之间找到一个最佳平衡点。下表介绍了这些设置。

自动扩缩设置 说明
目标 CPU 利用率 设置 CPU 使用率阈值,达到此阈值后,系统将启动更多实例来处理流量。
目标吞吐量利用率 设置并发请求数的吞吐量阈值,超出此阈值后,系统将启动更多实例来处理流量。
并发请求数上限 设置在调度器启动新实例之前,实例可以接受的最大并发请求数。

如需了解这些设置的效果,请观看 App Engine 新调度器设置视频。

缩减

当请求数量减少时,App Engine 会减少实例数量。这种缩减有助于确保应用的所有当前实例都用于优化效率和成本效益。

当应用完全空闲时,App Engine 会关闭其关联的动态实例,但可以在必要时立即重新加载这些动态实例。重新加载实例可能会导致加载请求,并因此造成用户的延迟时间增加。

您可以指定空闲实例数下限。根据请求数量为应用设置适当数量的空闲实例,这让应用能够以极短的延迟时间处理每个请求,遇到请求数量异常高的情形时除外。

扩缩和批量请求

如果向服务发送大批量请求(例如,发送到任务队列进行处理),则系统会快速创建大量实例。如果可能,我们建议通过限制速率(也就是限制每秒发送的请求数)来控制这一过程。例如,如果您使用 Tasks,则可以控制任务的推送速率

实例生命周期

实例状态

自动扩缩服务的实例始终处于运行中。但是,手动或基本扩缩服务的实例可能正在运行中或已停止。同一服务和版本的所有实例都具有相同的状态。您可以通过管理版本来更改实例的状态。您可以:

启动

收到启动请求(向 /_ah/start 发出的空白 HTTP GET 请求)时,系统会通过创建服务实例来做出响应。App Engine 会发送此请求以创建实例;用户无法向 /_ah/start 发送请求。手动扩缩和基本扩缩实例必须先响应启动请求,然后才能处理其他请求。启动请求可用于以下两个目的:

  • 启动无限期运行的程序,不再接受其他请求。
  • 在实例接收其他流量前对其进行初始化。

手动扩缩、基本扩缩和自动扩缩实例的启动方式有所不同。当您启动手动扩缩实例时,App Engine 会立即向每个实例发送 /_ah/start 请求。当您启动基本扩缩服务的实例时,App Engine 允许它接收流量,但直到实例收到它的第一个用户请求之后,App Engine 才会向其发送 /_ah/start 请求。只有在必要时才会启动多个基本扩缩实例,以处理增加的流量。自动扩缩实例不会收到任何 /_ah/start 请求。

如果某个实例以 HTTP 状态代码 200–299404 响应 /_ah/start 请求,系统会认为该实例已成功启动,可以处理其他请求。否则,App Engine 会终止该实例。手动扩缩实例会立即重启,而基本扩缩实例仅在需要处理流量时才会重启。

关停

关停过程可能由各种计划内和计划外事件触发,例如:

  • 手动停止实例。
  • 将新版本部署到服务。
  • 实例超过其配置的 instance_class 的最大内存。
  • 应用的实例小时数配额用尽。
  • 实例被移到其他机器,原因可能是当前运行该实例的机器重启,或者 App Engine 转移您的实例以改善负载分布情况。

加载请求

当 App Engine 为您的应用创建新实例时,该实例必须先加载处理请求所需的所有库和资源。这一过程在首次向实例发送请求期间发生,称为“加载请求”。在加载请求期间,您的应用会进行初始化,导致此类请求需要更长时间才能处理完毕。

以下最佳做法可让您缩短加载请求的时长:

  • 仅加载启动所需的代码。
  • 尽可能少访问磁盘。
  • 在某些情况下,从单个 zip 或 jar 文件加载代码比从许多个单独的文件加载代码速度要快。

预热请求

预热请求是特定类型的加载请求;预热请求会在发出任何实际请求前将应用代码加载到实例中。手动扩缩实例或基本扩缩实例不会收到 /_ah/warmup 请求。

如需详细了解如何使用预热请求,请参阅配置预热请求

实例正常运行时间

App Engine 会尝试保持手动和基本扩缩实例无限期运行。但是,目前无法保证手动和基本扩缩实例的正常运行时间。