Python 2 运行时环境

利用 App Engine,您可以使用 Python 编程语言构建 Web 应用,并且可以利用适用于 Python 的多种库、工具和框架。这些库、工具和框架可供专业开发者构建世界级的 Web 应用。您的 Python 应用将在 Google 的可扩展基础架构上运行,并可使用大规模永久性存储空间和服务。

简介

App Engine 在安全的“沙盒”环境中使用预先加载的 Python 解释器执行 Python 应用代码。应用会接收网络请求、执行操作并通过与此环境互动来发送响应。

Python 网络应用使用 WSGI 协议与 App Engine 网络服务器互动,因此应用可以使用任何与 WSGI 兼容的网络应用框架。App Engine 包含一个名为 webapp2 的简单网络应用框架,因此很容易上手。对于较大的应用,您可以利用成熟的第三方框架(例如 Django),这些第三方框架可与 App Engine 有效地配合使用。

Python 解释器可以运行任何 Python 代码,包括您为应用添加的 Python 模块,以及 Python 标准库。解释器无法使用 C 代码加载 Python 模块;它是一个纯粹的 Python 环境。

安全的“沙盒”环境可以隔离您的应用,以确保服务正常,安全无虞。它确保应用只能执行不会影响其他应用的性能和可扩缩性的操作。例如,应用不能将数据写入本地文件系统中,也不能随意建立网络连接。应用使用 App Engine 提供的可扩展服务来存储数据并通过互联网进行通信。当应用尝试从已知在沙盒限制内无法正常运行的标准库导入 Python 模块时,Python 解释器会引发异常。

App Engine 平台提供了多项可供您的代码调用的服务。您的应用还可以配置以指定间隔运行的计划任务

选择 Python 2 运行时

您可以在 app.yaml 配置文件中指定 Python 运行时环境,该文件用于将应用部署到 App Engine。例如,将以下代码添加到 app.yaml 文件以使用 Python 2.7 版

runtime: python27
api_version: 1
threadsafe: true
...

第一个元素 runtime 用于选择 Python 运行时环境。

第二个元素 api_version 选择要使用的 Python 运行时环境的版本。截止到撰写本文之时,App Engine 只有一个 Python 环境版本,即版本 1。如果 App Engine 团队需要针对环境发布更改,但更改的内容可能与现有代码不兼容,则将使用新版本的标识符来发布。在您更改 api_version 设置并上传应用之前,应用将继续使用以前选择的版本。

如需详细了解 app.yaml 文件以及如何将应用部署到 App Engine,请参阅 app.yaml 参考文档迁移到 Python 2.7部署 Python 应用等主题。

沙盒

为了让 App Engine 能够跨多个网络服务器分发应用请求,并防止应用之间相互干扰,应用需要在受限制的“沙盒”环境中运行。在此环境中,应用可以执行代码、存储和查询 Datastore 中的数据,使用 App Engine 邮件、URL Fetch 服务和 Users 服务,以及检查用户的 Web 请求并准备响应。

App Engine 应用不能有以下行为:

  • 写入文件系统。应用必须使用 Datastore 来存储持久性数据。应用可从文件系统中读取内容,并且可以使用随应用上传的所有应用文件。

  • 缓慢响应。向应用发出的 Web 请求必须在数秒内得到处理。需要很长时间才能做出响应的进程将被终止,以免网络服务器发生过载。

  • 进行其他类型的系统调用。

Python 中的沙盒化

使用 Python 2.7 运行时时,您可以上传和使用 .pyc 文件,但不能上传同一文件的 .py.pyc 版本。您可以上传包含 .py 和/或 .pyc 文件的 .zip 文件。如果上传 .pyc 文件,需要遵循一些重要的注意事项:

  • 对于 CGI 脚本,即使您上传 .pyc 文件,脚本处理程序仍应使用 .py 文件扩展名。
  • 默认情况下,.pyc 文件会在部署期间被跳过。您必须替换 app.yaml 文件中的 skip_files 元素,这样新值才不会导致 .pyc 文件被跳过。
  • 您必须使用 Python 2.7 来构建 .pyc 文件。如果您的开发机器上有其他版本的 Python(如 Python 2.6),则您需要获取 2.7 版才能构建兼容的 .pyc 文件。

纯 Python 2

Python 运行时环境中使用的所有代码必须是纯 Python,且不包括任何 C 扩展程序或其他必须编译的代码。

该环境包含 Python 标准库。有些模块已被停用,原因是 App Engine 不支持其核心功能(例如联网以及对文件系统执行写入操作)。此外,os 模块可以使用,但不受支持的功能已被停用。尝试导入不受支持的模块或使用不受支持的功能会引发异常。

标准库中的几个模块已被替换,或已经过自定义,可以与 App Engine 配合使用。这些模块因 Python 运行时版本而异,具体如下所述。

Python 2.7 版中的自定义库

在 Python 2.7 版运行时中,以下模块已被替换或经过自定义:

除了 Python 标准库和 App Engine 库之外,Python 2.7 版运行时还包含几个第三方库

添加第三方 Python 库

您可以在应用中添加第三方 Python 库,只需在应用目录中添加相应代码即可。如果您在应用目录中创建了指向库目录的符号链接,则该链接将可供访问,并且该库将包含在您部署到 App Engine 的应用中。

Python 模块的包含路径包含应用的根目录,该目录是包含 app.yaml 文件的目录。您在应用的根目录中创建的 Python 模块可以通过根目录中的路径访问。不要忘记在子目录中创建所需的 __init__.py 文件,以便 Python 将这些子目录识别为软件包。此外,还要确保您的库不需要任何 C 扩展程序

线程

在 Python 2.7 版中,可以使用 threadthreading 模块创建线程。请注意,当请求结束时,线程将由运行时连接,因此线程无法在请求结束之后运行。

后台线程

在具有手动或基本扩缩功能的实例上运行的代码可以启动后台线程,该线程可以比生成它的请求寿命更长。这允许实例执行任意的定期任务或计划任务,或者在请求已返回至用户后继续在后台运行。

后台线程的 os.environ 和日志记录条目与生成线程的 os.environ 和日志条目无关。

您必须从适用于 App Engine 的 SDK 导入 google.appengine.api.background_thread 模块。

from google.appengine.api import background_thread

BackgroundThread 类与常规 Python threading.Threadclass 类似,但可以比生成它的请求“寿命更长”。另外,start_new_background_thread() 函数会创建一个后台线程并启动该线程:

# sample function to run in a background thread
def change_val(arg):
    global val
    val = arg

if auto:
    # Start the new thread in one command
    background_thread.start_new_background_thread(change_val, ['Cat'])
else:
    # create a new thread and start it
    t = background_thread.BackgroundThread(
        target=change_val, args=['Cat'])
    t.start()
对于每个实例,App Engine API 最多创建 10 个并发后台线程。 (此限制不适用于与 App Engine API 无关的常规 Java 线程。)

工具

适用于 App Engine 的 SDK 包含各种工具,这些工具可用于测试应用、上传应用文件、管理 Datastore 索引、下载日志数据,以及将大量数据上传到 Datastore。

开发服务器在本地计算机上运行应用,以便对应用进行测试。服务器模拟 Datastore 服务和沙盒限制。开发服务器还可以根据应用在测试期间执行的查询生成 Datastore 索引的配置。

gcloud 工具可处理与 App Engine 上运行的应用进行的所有命令行交互操作。您可以使用 gcloud app deploy 将应用上传到 App Engine,或者更新单个配置文件,例如 Datastore 索引配置,它可让您在部署代码之前构建新索引。您还可以查看应用的日志数据,以便使用您自己的工具分析应用的性能。

并发和延迟

应用的延迟对处理流量所需的实例数量影响最大。如果您快速处理请求,则单个实例可以处理大量请求。

单线程实例可以处理一个并发请求。 因此,延迟时间与每秒可在实例上处理的请求数之间存在着直接关系。例如,10 毫秒的延迟时间等同于每个实例每秒处理 100 个请求。

多线程实例可以处理多个并发请求。因此,所用 CPU 与每秒请求数之间存在直接关系。

Python 2.7 版应用支持并发请求,因此单个实例可以在等待其他请求完成时处理新请求。并发处理能力可显著减少应用所需的实例数量,但您需要设计应用以实现多线程。

例如,如果 B4 实例(大约 2.4GHz)为每个请求消耗 10 个兆周期,则每个实例每秒可以处理 240 个请求。如果它为每个请求消耗 100 个兆周期,则每个实例每秒可以处理 24 个请求。这些数字是理想的情况,但就您可以在实例上完成的任务而言,它们相当贴近实际情况。

环境变量

以下环境变量由运行时设置:

环境变量 说明
GAE_APPLICATION App Engine 应用的 ID。此 ID 以“region code~”为前缀,例如“e~”(对于在欧洲部署的应用)。
GAE_DEPLOYMENT_ID 当前部署的 ID。
GAE_ENV App Engine 环境。设置为 standard
GAE_INSTANCE 当前运行您的服务的实例的 ID。
GAE_RUNTIME app.yaml 文件中指定的运行时环境。
GAE_SERVICE app.yaml 文件中指定的服务名称。如果未指定服务名称,则将其设置为 default
GAE_VERSION 服务的当前版本标签。
GOOGLE_CLOUD_PROJECT 与您的应用关联的 Google Cloud 项目 ID。
PORT 接收 HTTP 请求的端口。

您可以app.yaml 文件中定义其他环境变量,但不能替换上述值。