为 Azure 应用服务配置 Linux Python 应用
本文介绍 Azure 应用服务如何运行 Python 应用,如何将现有应用迁移到 Azure 以及如何按需自定义应用服务的行为。 必须连同所有必需的 pip 模块一起部署 Python 应用。
部署 Git 存储库或部署启用了生成自动化的 zip 包时,应用服务部署引擎会自动激活虚拟环境并运行 pip install -r requirements.txt
。
对于在应用服务中使用内置 Linux 容器的 Python 开发人员,本指南为其提供了关键概念和说明。 若从未使用过 Azure 应用服务,请先按照 Python 快速入门以及将 Python 与 PostgreSQL 配合使用教程进行操作。
可使用 Azure 门户 或 Azure CLI 进行配置:
Azure 门户,使用应用的“设置”>“配置”页面,如在 Azure 门户中配置应用服务应用中所述。
Azure CLI:
注意
Linux 是用于在应用服务中运行 Python 应用的唯一操作系统选项。 Windows 上的 Python 不再受支持。 但是,你可以生成自己的自定义 Windows 容器映像,然后在应用服务中运行该映像。 有关详细信息,请参阅使用自定义 Docker 映像。
配置 Python 版本
Azure 门户:使用“配置”页面上的“常规设置”选项卡,如配置 Linux 容器的常规设置中所述。
Azure CLI:
使用 az webapp config show 显示当前 Python 版本:
az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion
将
<resource-group-name>
和<app-name>
替换为适合 Web 应用的名称。使用 az webapp config set 设置 Python 版本
az webapp config set --resource-group <resource-group-name> --name <app-name> --linux-fx-version "PYTHON|3.11"
使用 az webapp list-runtimes 显示 Azure 应用服务中支持的所有 Python 版本:
az webapp list-runtimes --os linux | grep PYTHON
自定义生成自动化
在部署应用且将应用设置 SCM_DO_BUILD_DURING_DEPLOYMENT
设置为 1
时,应用服务的生成系统 Oryx 将执行以下步骤:
如果该步骤由
PRE_BUILD_COMMAND
设置指定,请运行自定义预生成脚本。 (该脚本自身可运行其他 Python 和 Node.js 脚本、pip 和 npm 命令,以及 yarn 等基于节点的工具,例如yarn install
和yarn build
。)运行
pip install -r requirements.txt
。 requirements.txt 文件必须存在于项目的根文件夹中。 否则,生成过程将报告错误:“找不到 setup.py 或 requirements.txt;未运行 pip install。”如果在存储库的根文件夹中找到了 manage.py(指示 Django 应用),则运行 manage.py collectstatic 。 但如果
DISABLE_COLLECTSTATIC
设置为true
,则跳过此步骤。如果该步骤由
POST_BUILD_COMMAND
设置指定,请运行自定义生成后脚本。 (同样,该脚本也可运行其他 Python 和 Node.js 脚本、pip 和 npm 命令,以及基于节点的工具。)
默认情况下,PRE_BUILD_COMMAND
、POST_BUILD_COMMAND
和 DISABLE_COLLECTSTATIC
设置为空。
若要在生成 Django 应用时禁用正在运行的 collectstatic,请将
DISABLE_COLLECTSTATIC
设置设置为true
。若要运行预生成命令,请将
PRE_BUILD_COMMAND
设置设置为包含命令(例如echo Pre-build command
)或相对于项目根目录的脚本文件的路径(例如scripts/prebuild.sh
)。 所有命令都必须使用项目根文件夹的相对路径。若要运行生成后命令,请将
POST_BUILD_COMMAND
设置设置为包含命令(例如echo Post-build command
)或相对于项目根目录的脚本文件的路径(例如scripts/postbuild.sh
)。 所有命令都必须使用项目根文件夹的相对路径。
有关用于自定义生成自动化的其他设置,请参阅 Oryx 配置。
若要访问生成和部署日志,请参阅访问部署日志。
若要详细了解应用服务如何在 Linux 中运行和生成 Python 应用,请参阅 Oryx 如何检测和生成 Python 应用。
注意
PRE_BUILD_SCRIPT_PATH
和 POST_BUILD_SCRIPT_PATH
设置与 PRE_BUILD_COMMAND
和 POST_BUILD_COMMAND
相同,并且支持用于旧用途。
如果名为 SCM_DO_BUILD_DURING_DEPLOYMENT
的设置包含 true
或 1
,则会在部署期间触发 Oryx 生成。 使用 git、Azure CLI 命令 az webapp up
和 Visual Studio Code 部署时,该设置为 true
。
注意
始终在所有预先生成和后期生成脚本中使用相对路径,因为运行 Oryx 的生成容器与运行应用的运行时容器不同。 决不要依赖于应用项目文件夹在容器中的确切位置(例如,其位于 site/wwwroot 下)。
将现有应用程序迁移到 Azure
可以将现有的 Web 应用程序重新部署到 Azure,如下所示:
源存储库:在适当的存储库(如 GitHub)中维护源代码,确保可以在此过程的稍后部分设置持续部署。
- requirements.txt 文件必须位于存储库的根目录,应用服务才能自动安装必需的包。
数据库:如果应用依赖于数据库,则还应在 Azure 上创建必需的资源。
应用服务资源:创建资源组、应用服务计划和应用服务 Web 应用以托管应用程序。 可通过运行 Azure CLI 命令
az webapp up
轻松执行此操作。 也可以按教程:使用 PostgreSQL 部署 Python(Django 或 Flask)Web 应用中的说明来创建和部署资源。 替换资源组、应用服务计划和 Web 应用的名称,使其更适用于应用程序。环境变量:如果应用程序需要使用任意环境变量,请创建等效的应用服务应用程序设置。 这些应用服务设置在代码中显示为环境变量,如访问环境变量中所述。
- 例如,通常通过此类设置来管理数据库连接,如教程:使用 PostgreSQL 部署 Django Web 应用 - 验证连接设置所示。
- 有关典型 Django 应用的具体设置,请参阅 Django 应用的生产设置。
应用启动:查看后文中的容器启动过程部分,了解应用服务如何尝试运行应用。 默认情况下,应用服务使用 Gunicorn Web 服务器,该服务器必须能够找到应用对象或 wsgi.py 文件夹。 如果需要,可以自定义启动命令。
持续部署:按照持续部署到 Azure 应用服务一文所述,从 GitHub Actions、Bitbucket 或 Azure Repos 设置持续部署。 或者,按照从本地 Git 部署到 Azure 应用服务一文所述,设置从本地 Git 进行的持续部署。
自定义操作:若要在托管应用的应用服务容器内执行操作(例如 Django 数据库迁移),可以通过 SSH 连接到容器。 有关运行 Django 数据库迁移的示例,请参阅教程:使用 PostgreSQL 部署 Django Web 应用 - 生成数据库架构。
- 使用持续部署时,可以使用生成后命令执行这些操作,如前面的自定义生成自动化所述。
完成这些步骤后,你应能够将更改提交到源存储库,并将这些更新自动部署到应用服务。
Django 应用的生产设置
对于 Azure 应用服务等生产环境,Django 应用应遵循 Django 的部署清单。
下表描述了与 Azure 相关的生产设置。 这些设置在应用的 setting.py 文件中定义。
Django 设置 | Azure 说明 |
---|---|
SECRET_KEY |
如访问作为环境变量的应用设置所述,请将值存储在应用服务设置中。 你也可以在 Azure 密钥保管库中将该值存储为“机密”。 |
DEBUG |
在应用服务上创建一个值为 0 (false) 的 DEBUG 设置,然后将该值加载为环境变量。 在开发环境中,创建一个值为 1 (true) 的 DEBUG 环境变量。 |
ALLOWED_HOSTS |
在生产环境中,Django 要求在“settings.py”的 ALLOWED_HOSTS 数组中包含应用的 URL。 可以使用代码 os.environ['WEBSITE_HOSTNAME'] 在运行时检索此 URL。 应用服务会自动将 WEBSITE_HOSTNAME 环境变量设置为应用的 URL。 |
DATABASES |
在应用服务中为数据库连接定义设置,并将这些设置加载为环境变量以填充 DATABASES 字典。 也可以将值(尤其是用户名和密码)存储为 Azure Key Vault 机密。 |
提供 Django 应用的静态文件
如果 Django Web 应用包含静态前端文件,请先按照 Django 文档中有关管理静态文件的说明进行操作。
然后,对应用服务进行以下修改:
请考虑使用环境变量(对于本地开发)和应用设置(部署到云时)动态设置 Django 变量
STATIC_URL
和STATIC_ROOT
。 例如:STATIC_URL = os.environ.get("DJANGO_STATIC_URL", "/static/") STATIC_ROOT = os.environ.get("DJANGO_STATIC_ROOT", "./static/")
可根据需要更改本地环境和云环境的
DJANGO_STATIC_URL
和DJANGO_STATIC_ROOT
。 例如,如果静态文件的生成过程将其置于名为django-static
的文件夹中,那么你可将DJANGO_STATIC_URL
设置为/django-static/
,以避免使用默认值。如果你有一个预生成脚本,且它在其他文件夹中生成静态文件,请将该文件夹添加到 Django 变量
STATICFILES_DIRS
中,以便 Django 的collectstatic
进程查找它们。 例如,如果你在前端文件夹中运行yarn build
,并且 yarn 生成包含静态文件的build/static
文件夹,则请按如下所示添加该文件夹:FRONTEND_DIR = "path-to-frontend-folder" STATICFILES_DIRS = [os.path.join(FRONTEND_DIR, 'build', 'static')]
此处是
FRONTEND_DIR
,它用于生成一个指向运行 yarn 等生成工具的位置的路径。 你可根据需要再次使用环境变量和应用设置。将
whitenoise
添加到 requirements.txt 文件。 WhiteNoise (whitenoise.evans.io) 是一种 Python 包,可使生产 Django 应用轻松地为自己的静态文件提供服务。 WhiteNoise 专门为在 DjangoSTATIC_ROOT
变量指定的文件夹中找到的文件提供服务。在 settings.py 文件中,为 WhiteNoise 添加以下行:
STATICFILES_STORAGE = ('whitenoise.storage.CompressedManifestStaticFilesStorage')
同时修改
MIDDLEWARE
和INSTALLED_APPS
列表以包含 WhiteNoiseMIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # Add whitenoise middleware after the security middleware 'whitenoise.middleware.WhiteNoiseMiddleware', # Other values follow ] INSTALLED_APPS = [ "whitenoise.runserver_nostatic", # Other values follow ]
提供 Flask 应用的静态文件
如果 Flask Web 应用包含静态前端文件,请先按照 Flask 文档中有关管理静态文件的说明进行操作。 有关如何在 Flask 应用程序中提供静态文件的示例,请参阅 GitHub 上的示例 Flask 应用程序。
若要直接从应用程序中的路由提供静态文件,可以使用 send_from_directory
方法:
from flask import send_from_directory
@app.route('/reports/<path:path>')
def send_report(path):
return send_from_directory('reports', path)
容器特征
部署到应用服务时,Python 应用在应用服务 Python GitHub 存储库中定义的 Linux Docker 容器内运行。 可以在特定于版本的目录中找到映像配置。
此容器具有以下特征:
应用是结合附加参数
--bind=0.0.0.0 --timeout 600
,使用 Gunicorn WSGI HTTP Server 运行的。可以通过自定义启动命令为 Gunicorn 提供配置设置。
若要使 Web 应用免受意外或蓄意的 DDOS 攻击,Gunicorn 在 Nginx 反向代理后运行,如部署 Gunicorn 中所述。
默认情况下,基础容器映像仅包含 Flask Web 框架,但容器支持符合 WSGI 规范并与 Python 3.6+ 兼容的其他框架,例如 Django。
若要安装其他包(例如 Django),请在项目的根目录中创建 requirements.txt 文件,该文件指定直接依赖项。 然后,部署项目时,应用服务会自动安装这些依赖项。
requirements.txt 文件必须位于项目根文件夹中,依赖项才能安装 。 否则,生成过程将报告错误:“找不到 setup.py 或 requirements.txt;未运行 pip install”。如果遇到此错误,请检查 requirements 文件的位置。
应用服务使用 Web 应用的 URL 自动定义名为
WEBSITE_HOSTNAME
的环境变量,例如msdocs-hello-world.chinacloudsites.cn
。 它还使用应用的名称定义WEBSITE_SITE_NAME
,例如msdocs-hello-world
。npm 和 Node.js 安装在容器中,因此你可运行基于节点的生成工具,例如 yarn。
容器启动过程
在启动期间,Linux 上的应用服务容器将运行以下步骤:
- 使用自定义启动命令(如果已提供)。
- 检查是否存在 Django 应用,如果已检测到,请为其启动 Gunicorn。
- 检查是否存在 Flask 应用,如果已检测到,请为其启动 Gunicorn。
- 如果未找到其他任何应用,则启动容器中内置的默认应用。
以下部分详细介绍了每个选项。
Django 应用
对于 Django 应用,应用服务将在应用代码中查找名为 wsgi.py
的文件,然后使用以下命令运行 Gunicorn:
# <module> is the name of the folder that contains wsgi.py
gunicorn --bind=0.0.0.0 --timeout 600 <module>.wsgi
如果想要对启动命令进行更具体的控制,请使用自定义启动命令,将 <module>
替换为包含 wsgi.py 的文件夹的名称,如果该模块不在项目根目录中,则添加一个 --chdir
参数。 例如,如果 wsgi.py 位于项目根文件夹中的 knboard/backend/config 下,请使用参数 --chdir knboard/backend config.wsgi
。
若要启用生产日志记录,请按照自定义启动命令示例中所示,添加 --access-logfile
和 --error-logfile
参数。
Flask 应用
对于 Flask,应用服务将查找名为 application.py 或 app.py 的文件并启动 Gunicorn,如下所示:
# If application.py
gunicorn --bind=0.0.0.0 --timeout 600 application:app
# If app.py
gunicorn --bind=0.0.0.0 --timeout 600 app:app
如果主应用模块包含在不同的文件中,则对应用对象使用不同的名称。 如果要向 Gunicorn 提供其他参数,请使用自定义启动命令。
默认行为
如果应用服务找不到自定义命令、Django 应用或 Flask 应用,它会运行位于 opt/defaultsite 文件夹中的默认只读应用(如下图所示)。
如果部署代码后仍看到默认应用,请参阅故障排除 - 应用未显示。
自定义启动命令
可以通过在启动命令文件中提供自定义启动命令或多个命令来控制容器的启动行为。 启动命令文件可使用你选择的任何名称,例如 startup.sh、startup.cmd、startup.txt 等 。
所有命令都必须使用项目根文件夹的相对路径。
指定启动命令或命令文件:
Azure 门户:选择应用的“配置”页,然后选择“常规设置” 。 在“启动命令”字段中,输入启动命令的全文或启动命令文件的名称。 然后,选择“保存”,应用所做的更改。 请参阅针对 Linux 容器的配置常规设置。
Azure CLI:使用 az webapp config set 命令和
--startup-file
参数来设置启动命令或文件:az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<custom-command>"
将
<custom-command>
替换为启动命令的全文或启动命令文件的名称。
应用服务将忽略处理自定义启动命令或文件时出现的任何错误,然后通过查找 Django 和 Flask 应用来继续执行其启动过程。 如果看不到预期的行为,请检查启动命令或文件是否没有错误,以及启动命令文件是否与应用代码一起部署到应用服务。 还可检查诊断日志以获取更多信息。
示例启动命令
添加了 Gunicorn 参数:以下示例将
--workers=4
参数添加到用于启动 Django 应用的 Gunicorn 命令行:# <module-path> is the relative path to the folder that contains the module # that contains wsgi.py; <module> is the name of the folder containing wsgi.py. gunicorn --bind=0.0.0.0 --timeout 600 --workers=4 --chdir <module_path> <module>.wsgi
有关详细信息,请参阅“运行 Gunicorn”。 如果使用自动缩放规则来纵向扩展和缩减 Web 应用,则还应在启动命令中使用
NUM_CORES
环境变量来动态设置 gunicorn 辅助角色的数量,例如--workers $((($NUM_CORES*2)+1))
。为 Django 启动生产日志记录: 将
--access-logfile '-'
和--error-logfile '-'
参数添加到命令行:# '-' for the log files means stdout for --access-logfile and stderr for --error-logfile. gunicorn --bind=0.0.0.0 --timeout 600 --workers=4 --chdir <module_path> <module>.wsgi --access-logfile '-' --error-logfile '-'
这些日志将显示在应用服务日志流中。
有关详细信息,请参阅 Gunicorn 日志记录。
自定义 Flask 主模块:默认情况下,应用服务假定 Flask 应用的主模块是 application.py 或 app.py。 如果主模块使用其他名称,则必须自定义启动命令。 例如,如果 Flask 应用的主模块是 hello.py,而该文件中的 Flask 应用对象名为
myapp
,则命令如下所示:gunicorn --bind=0.0.0.0 --timeout 600 hello:myapp
如果主模块位于子文件夹(例如
website
)中,请使用--chdir
参数指定该文件夹:gunicorn --bind=0.0.0.0 --timeout 600 --chdir website hello:myapp
使用非 Gunicorn 服务器:若要使用其他 web 服务器(如 aiohttp),请使用适当的命令作为启动命令或在启动命令文件中使用:
python3.7 -m aiohttp.web -H localhost -P 8080 package.module:init_func
作为环境变量访问应用设置
应用设置是专门为应用存储在云中的值,如配置应用设置中所述。 这些设置可以作为环境变量提供给应用代码,并使用标准的 os.environ 模式进行访问。
例如,如果已创建名为 DATABASE_SERVER
的应用设置,则以下代码将检索该设置的值:
db_server = os.environ['DATABASE_SERVER']
检测 HTTPS 会话
在应用服务中,TLS/SSL 终止在网络负载均衡器上发生,因此,所有 HTTPS 请求将以未加密的 HTTP 请求形式访问你的应用。 如果应用逻辑需要检查用户请求是否已加密,可以检查 X-Forwarded-Proto
标头。
if 'X-Forwarded-Proto' in request.headers and request.headers['X-Forwarded-Proto'] == 'https':
# Do something when HTTPS is used
使用常用 Web 框架可以访问采用标准应用模式的 X-Forwarded-*
信息。 例如,在 Django 中,可以使用 SECURE_PROXY_SSL_HEADER 告知 Django 使用 X-Forwarded-Proto
标头。
访问诊断日志
可以访问在容器中生成的控制台日志。
首先,请运行以下命令,以便启用容器日志记录功能:
az webapp log config --name <app-name> --resource-group <resource-group-name> --docker-container-logging filesystem
将 <app-name>
和 <resource-group-name>
替换为适合 Web 应用的名称。
启用容器日志记录功能以后,请运行以下命令来查看日志流:
az webapp log tail --name <app-name> --resource-group <resource-group-name>
如果没有立即看到控制台日志,请在 30 秒后重新查看。
若要随时停止日志流式处理,可键入 CtrlC。
也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker
中检查日志文件。
若要通过 Azure 门户访问日志,请在应用的左侧菜单中选择“监视”>“日志流” 。
访问部署日志
当你部署代码时,应用服务会执行前面的自定义生成自动化部分所述的生成过程。 由于生成过程在自己的容器中运行,因此,生成日志与应用的诊断日志分开存储。
通过以下步骤访问部署日志:
- 在 Web 应用的 Azure 门户上,选择左侧菜单中的“部署”>“部署中心”。
- 在“日志”选项卡上,选择最新提交的“提交 ID”。
- 在出现的“日志详细信息”页上,选择“正在运行 oryx 生成...”旁边显示的“显示日志...”链接。
生成问题(如 requirements.txt 中不正确的依赖项)以及生成前或生成后脚本中的错误都会显示在这些日志中。 如果 requirements 文件没有命名为 requirements.txt 或者没有出现在项目的根文件夹中,也会出现错误。
在浏览器中打开 SSH 会话
若要通过容器打开直接的 SSH 会话,应用应该处于正在运行状态。
将以下 URL 粘贴到浏览器中,将 <app-name>
替换为应用名称:
https://<app-name>.scm.chinacloudsites.cn/webssh/host
如果尚未进行身份验证,则需通过要连接的 Azure 订阅进行身份验证。 完成身份验证以后,可以看到一个浏览器内 shell,可以在其中的容器中运行命令。
注意
在 /home 目录之外进行的任何更改均存储在容器本身中,在应用重启后不保留。
若要从本地计算机打开远程 SSH 会话,请参阅从远程 shell 打开 SSH 会话。
成功连接到 SSH 会话后,应该会在窗口底部显示“已建立 SSH 连接”消息。 如果显示诸如“SSH_CONNECTION_CLOSED”之类的错误或容器重启消息,则表明可能有错误阻止应用容器启动。 有关调查可能存在的问题的步骤,请参阅故障排除。
URL 重写
在适用于 Linux 的 Azure 应用服务上部署 Python 应用程序时,可能需要处理应用程序内的 URL 重写。 这对于确保在不依赖外部 Web 服务器配置的情况下将特定 URL 模式重定向到正确的终结点尤为有用。 对于 Flask 应用程序,可以使用 URL 处理器和自定义中间件来实现此目的。 在 Django 应用程序中,可靠的 URL 调度程序可以高效地管理 URL 重写。
应用未显示
部署自己的应用代码后看到默认应用。 之所以显示默认应用,是因为并未将应用代码部署到应用服务,或者应用服务未找到应用代码,因此运行了默认应用。
请重启应用服务,等待 15 到 20 秒,然后再次检查应用。
使用 SSH 直接连接到应用服务容器,并验证文件是否在 site/wwwroot 下。 如果不在,请执行以下步骤:
- 创建一个名为
SCM_DO_BUILD_DURING_DEPLOYMENT
且值为 1 的应用设置,重新部署代码,等待几分钟,然后再次尝试访问应用。 有关创建应用设置的详细信息,请参阅在 Azure 门户中配置应用服务应用。 - 查看部署过程,检查部署日志,更正所有错误,然后重新部署应用。
- 创建一个名为
如果这些文件存在,则表示应用服务无法识别特定的启动文件。 检查是否按应用服务的预期方式为 Django 或 Flask 构建了应用,或使用自定义启动命令。
浏览器中显示“服务不可用”消息。浏览器在等待应用服务的响应时超时,这表示应用服务已启动 Gunicorn 服务器,但应用本身未启动。 这种情况可能表示 Gunicorn 参数不正确,或者应用代码有错误。
找不到 setup.py 或 requirements.txt
日志流显示“找不到 setup.py 或 requirements.txt;未运行 pip install。”:Oryx 生成过程找不到 requirements.txt 文件。
- 通过 SSH 连接到 Web 应用的容器,并验证 requirements.txt 的命名是否正确,以及是否就在 site/wwwroot 下。 如果该文件不存在,请使该文件存在于存储库中,并包含在部署中。 如果它存在于单独的文件夹中,请将其移到根文件夹下。
应用启动时出现 ModuleNotFoundError
如果看到类似于 ModuleNotFoundError: No module named 'example'
的错误,则在应用程序启动时,Python 会找不到一个或多个模块。 使用代码来部署虚拟环境时最常发生此错误。 虚拟环境不是可移植的,因此不应使用应用程序代码来部署虚拟环境。 而应利用 Oryx 来创建虚拟环境,然后创建应用设置 SCM_DO_BUILD_DURING_DEPLOYMENT
并将其设置为 1
,通过这种方法在 Web 应用上安装包。 此设置会强制 Oryx 安装你的包(无论何时部署到应用服务)。 有关详细信息,请参阅这篇有关虚拟环境可移植性的文章。
数据库已锁定
尝试使用 Django 应用运行数据库迁移时,可能会看到“sqlite3. OperationalError: 数据库已锁定。"此错误表示你的应用程序正在使用默认情况下配置了 Django 的 SQLite 数据库,而没有使用云数据库(如 Azure Database for PostgreSQL)。
检查应用的 settings.py 文件中的 DATABASES
变量,以确保应用使用的是云数据库,而不是 SQLite。
如果在使用教程:使用 PostgreSQL 部署 Django Web 应用中的示例时遇到此错误,请检查是否已完成验证连接设置中的步骤。
其他问题
在 SSH 会话中键入密码时,密码不显示:出于安全考虑,SSH 会话会在你键入密码时隐藏密码。 但是,这些字符会被记录下来,因此,请照常键入密码,完成后选择 Enter。
SSH 会话中的命令似乎已中断:编辑器可能不是换行命令,但它们仍应正常运行。
静态资产未在 Django 应用中显示:确保已启用 WhiteNoise 模块。
你看到消息“致命错误: 需要建立 SSL 连接” :检查任何用于从应用内部访问资源(如数据库)的用户名和密码。