请求的处理方式

区域 ID

REGION_ID 是 Google 根据您在创建应用时选择的区域分配的缩写代码。此代码不对应于国家/地区或省,尽管某些区域 ID 可能类似于常用国家/地区代码和省代码。对于 2020 年 2 月以后创建的应用,REGION_ID.r 包含在 App Engine 网址中。对于在此日期之前创建的现有应用,网址中的区域 ID 是可选的。

详细了解区域 ID

本文档介绍了 App Engine 应用接收请求和发送响应的方式。

如需了解详情,请参阅请求标头和响应参考

如果您的应用使用多项服务,您可以将请求路由到特定服务或服务特定版本。如需详细了解服务可寻址性,请参阅请求的路由方式

处理请求

应用负责启动 Web 服务器和处理请求。您可以使用支持您的开发语言的任何 Web 框架。

App Engine 运行应用的多个实例,每个实例都有自己的 Web 服务器来处理请求。请求都可以路由到任何实例,因此来自同一用户的连续请求并不一定会发送到同一实例。一个实例可以并行处理多个请求。系统会根据流量的变化自动调整实例数量。您还可以通过在 app.yaml 文件中设置 max_concurrent_requests 元素,更改一个实例可处理的并发请求数量。

通过比较请求的网址和应用的 app.yaml 配置文件中的网址格式,服务器可确定要运行哪个 PHP 处理程序脚本。然后,服务器会运行填充了请求数据的脚本。服务器会将请求数据放入环境变量和标准输入流中。脚本会执行请求所需的操作,然后准备响应并将响应置于标准输出流上。

以下示例是一个 PHP 脚本,它会响应任何带有“Hello World!”消息的 HTTP 请求。

<?php

echo 'Hello, World!';

配额和限制

App Engine 会随着流量的增加自动为您的应用分配资源。但是,这一过程会受到下列限制:

  • App Engine 会为低延时应用(应用响应请求的时间少于 1 秒)预留自动扩缩容量。

  • 严重受 CPU 限制的应用还可能发生额外的延时,以便与同一服务器上的其他应用有效地共享资源。静态文件请求不受这些延迟限制的影响。

发送到应用的所有传入请求都会计入请求限额。为响应请求而发送的数据会计入传出带宽(计费)限额。

HTTP 和 HTTPS(安全)请求均计入请求传入带宽(计费)传出带宽(计费)限额。Google Cloud 控制台的“配额详情”页面还会分别列出安全请求次数安全传入带宽安全传出带宽的值,以供参考。仅 HTTPS 请求计入这些值。如需了解详情,请参阅配额页面。

以下限制仅适用于请求处理程序的使用:

限制 金额
请求大小 32 MB
响应大小 32 MB
请求超时 取决于应用使用的扩缩类型
最大文件(应用文件和静态文件)总数 总共 10,000 个
每个目录 1,000 个
应用文件的最大大小 32 MB
静态文件的最大大小 32 MB
所有应用文件和静态文件的最大总大小 第 1 GB 免费
超出 1 GB 后,每 GB 每月收取 $ 0.026
待处理请求超时 10 秒
单个请求标头字段的大小上限 对于标准环境中的第二代运行时,大小上限为 8 千字节。对这些运行时的请求,如果标头字段超过 8 千字节,将返回 HTTP 400 错误。

请求限制

转发到应用服务器时,所有 HTTP/2 请求都将转换为 HTTP/1.1 请求。

响应限制

  • 动态响应上限为 32 MB。如果脚本处理程序生成的响应大于此限额,则服务器会发回一个包含 500 Internal Server Error 状态代码的空响应。此限额不适用于从 Cloud Storage 传送数据的响应。

  • 对于第二代运行时,响应标头上限为 8 KB。超出此上限的响应标头将返回 HTTP 502 错误,并显示日志 upstream sent too big header while reading response header from upstream

请求标头

传入 HTTP 请求包含客户端发送的 HTTP 标头。为保证安全,部分标头在到达应用前由中间代理进行清理或修改。

如需了解详情,请参阅请求标头参考文档

处理请求超时

App Engine 针对那些具有短暂请求寿命(通常为几百毫秒)的应用进行了优化。高效的应用可以对大多数请求作出快速响应。响应缓慢的应用将无法配合 App Engine 的基础架构良好地进行扩缩。为了确保此性能水平,系统施加了请求超时上限,每个应用都必须在此时间内响应。

如果 PHP 脚本超过此截止时间,系统将设置连接状态位字段上的 TIMEOUT 位。然后,脚本将有短暂的第二个截止时间,以清理任何长时间运行的任务并返回对用户的响应。

如果脚本在第二个截止时间之前未返回响应,则系统会停止处理程序,并返回默认的错误响应。

响应

App Engine 调用填充了 $_REQUEST 数组的脚本,缓冲此脚本的所有输出,并且在此脚本执行完毕后,将缓冲输出发送给最终用户。

您生成的响应会受到一些大小限制,而且响应在返回客户端之前可以修改。

如需了解详情,请参阅请求响应参考文档

流式响应

App Engine 不支持流式响应(这种响应方式在处理请求的同时将数据以增量数据块的形式分多次发送到客户端),来自您的代码的所有数据会以前述方式收集,并作为单个 HTTP 响应一次性发送。

响应压缩

App Engine 会尽其所能为支持压缩(Gzip 格式)内容的客户端提供这些内容。为了确定是否应压缩内容,App Engine 在收到请求时会执行以下操作:

  1. 通过查看请求中的 Accept-EncodingUser-Agent 标头,确认客户端能否可靠地接收压缩响应。此方法可避免常用浏览器中的 Gzip 压缩内容出现一些常见错误。

  2. 通过查看您为响应处理程序配置Content-Type 标头,确定内容压缩是否合适。一般而言,压缩适用于基于文本的内容类型,而不适用于二进制内容类型。

注意事项:

  • 客户端可以通过将 Accept-EncodingUser-Agent 请求标头都设置为 gzip 来强制压缩基于文本的内容类型。

  • 如果请求未在 Accept-Encoding 标头中指定 gzip,则 App Engine 不会压缩响应数据。

  • Google Frontend 缓存来自 App Engine 静态文件和目录处理程序的响应。根据不同的因素(例如,首先缓存的响应数据类型、您在响应中指定的 Vary 标头以及请求中包含的标头),客户端可以请求压缩的数据但接收未压缩的数据,反之亦然。如需了解详情,请参阅响应缓存

响应缓存

Google Frontend 以及用户的浏览器和其他中间缓存代理服务器将按照您在响应中指定的标准缓存标头来缓存应用的响应。您可以通过框架在代码中直接指定这些响应标头,也可以通过 App Engine 静态文件和目录处理程序指定这些响应标头。

在 Google Frontend 中,缓存键是请求的完整网址。

缓存静态内容

如需确保客户端可始终收到发布的静态内容更新,我们建议您从版本化目录(例如 css/v1/styles.css)传送静态内容。在缓存过期之前,Google Frontend 不会验证缓存(检查更新的内容)。即使缓存过期,缓存只有在请求网址中的内容发生更改时才会更新。

app.yaml 中设置的以下响应标头会影响 Google Frontend 缓存内容的方式和时间:

  • Cache-Control 应设置为 public,以便 Google Frontend 缓存内容;除非指定了 Cache-Control privateno-store 指令,否则 Google Frontend 也可能会缓存它。如果您未在 app.yaml 中设置此标头,App Engine 会自动为由静态文件或目录处理程序处理的所有响应添加此标头。如需了解详情,请参阅添加或替换标头

  • Vary:如需使缓存根据请求中发送的标头返回网址的不同响应,请在 Vary 响应标头设置以下一个或多个值:AcceptAccept-EncodingOriginX-Origin

    由于可能会产生高基数,因此系统不会为其他 Vary 值缓存数据。

    例如:

    1. 您指定了以下响应标头:

      Vary: Accept-Encoding

    2. 应用收到的请求包含 Accept-Encoding: gzip 标头。App Engine 返回压缩响应,并且 Google Frontend 会缓存响应数据的 Gzip 版本。包含 Accept-Encoding: gzip 标头的网址的所有后续请求都将接收来自缓存的 Gzip 数据,直到缓存失效(由于内容在缓存过期后会发生变化)。

    3. 应用收到的请求不包含 Accept-Encoding 标头。App Engine 返回未压缩的响应,并且 Google Frontend 会缓存响应数据的未压缩版本。不包含 Accept-Encoding 标头的网址所有后续请求都会接收来自缓存的压缩数据,直到缓存失效为止。

    如果您未指定 Vary 响应标头,则 Google Frontend 将为网址创建一个缓存条目,并将其用于所有请求(无论请求中的标头如何)。例如:

    1. 您未指定 Vary: Accept-Encoding 响应标头。
    2. 请求包含 Accept-Encoding: gzip 标头,系统会缓存响应数据的 Gzip 版本。
    3. 第二个请求不包含 Accept-Encoding: gzip 标头。但是,由于缓存包含响应数据的 Gzip 版本,因此,即使客户端请求未压缩的数据,该响应也会经过 Gzip 压缩。

请求中的标头也会影响缓存:

  • 如果请求包含 Authorization 标头,则 Google Frontend 不会缓存该内容。

缓存到期

默认情况下,App Engine 静态文件和目录处理程序添加到响应的缓存标头会指示客户端和 Web 代理(如 Google Frontend)使缓存在 10 分钟后过期。

在传输指定了到期时间的文件后,即使用户清除了自己的浏览器缓存,通常也无法将文件从 Web 代理缓存中清除。重新部署应用的新版本将不会重置任何缓存。因此,如果您打算修改某个静态文件,则应该设置较短的到期时间(不超过一个小时)。在大多数情况下,默认的 10 分钟到期时间是合适的。

您可以通过在 app.yaml 文件中指定 default_expiration 元素,更改所有静态文件和目录处理程序的默认到期时间。如需为个别处理程序设置特定的到期时间,请在 app.yaml 文件中的相应处理程序元素内指定 expiration 元素。

您在到期元素时间中指定的值将用于设置 Cache-ControlExpires HTTP 响应标头。

应用缓存

PHP 运行时环境包括 OPcache,后者可以缓存 PHP 中间代码并明显缩短应用的响应时间。您可以通过在应用的 php.ini 文件中设置 opcache.enabled = "0" 来停用 OPcache 缓存。

日志记录

App Engine Web 服务器会捕获处理程序脚本为响应 Web 请求而写入标准输出流的所有内容。它还会捕获处理程序脚本写入标准错误流的所有内容,并将其存储为日志数据。您可以使用 Cloud Logging 在 Google Cloud 控制台中查看应用的日志数据。

App Engine PHP 运行时环境支持使用 PHP 的内置 syslog() 函数(该函数会调用 Logs API)记录应用的任意消息。

环境

强制 HTTPS 连接

出于安全考虑,所有应用都应建议客户端使用 https 连接。如需指示浏览器为给定页面或整个网域使用 https 而不是 http,请在响应中设置 Strict-Transport-Security。例如:

Strict-Transport-Security: max-age=31536000; includeSubDomains
如需为应用传送的任何静态内容设置此标头,请将该标头添加到应用的静态文件和目录处理程序

处理异步后台工作

后台工作是指您的应用在传送 HTTP 响应后为请求执行的任何工作。避免在应用中执行后台工作,并审核代码,以确保所有异步操作都会在传送响应之前完成。

对于长时间运行的作业,我们建议使用 Cloud Tasks。使用 Cloud Tasks 时,HTTP 请求会长期有效,并且仅在任何异步工作结束后返回响应。