在多个环境中工作
原文: Working with Multiple Environments
作者: Steve Smith
翻译: 刘浩杨
校对: 孟帅洋(书缘)
ASP.NET Core 介绍了支持在多个环境中管理应用程序行为的改进,如开发(development),预演(staging)和生产(production)。环境变量用来指示应用程序正在运行的环境,允许应用程序适当地配置。
章节:
开发,预演,生产
ASP.NET Core 引用了一个特定的环境变量 ASPNETCORE_ENVIRONMENT
来描述应用程序当前运行的环境。这个变量可以被设置为任何你喜欢的值,但是有三个值被约定使用: Development
,Staging
和 Production
。你会发现这些值在 ASP.NET Core 提供的示例和模板中被使用。
当前的环境设置可以通过编程方式从应用程序中被检测到。除此之外,你可以基于当前的应用程序环境在你的 view 里使用环境 tag helper 来包含某些部分。
注意
指定的环境变量名称不区分大小写。无论你把变量设置为Development
或者development
或者DEVELOPMENT
的结果将会是相同的。
开发
这应该是在开发应用程序时所使用的环境。当使用 Visual Studio 时,这个设置可以在项目的调试配置文件中指定,比如 IIS Express,在这里显示:
当你修改该项目创建的默认设置,你的更改会保留在 Properties
文件夹的 launchSettings.json 文件中。这个文件对于 Visual Studio 中每一个用来启动应用程序的配置文件都包含特定的设置,包括应该使用的任何环境变量。(在 servers 中更详细的讨论了调试配置文件)。例如,添加另一个 profile 配置来使用 IIS Express,使用 Staging
作为 ASPNETCORE_ENVIRONMENT
的值,在我们的示例项目中 launchSettings.json
文件如下图所示:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:40088/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express (Staging)": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Staging"
}
}
}
}
注意
项目配置文件或 launchSettings.json 所做的更改在使用的 web 服务器重启之前可能不会直接生效(尤其是, kestrel 在将要检测它的环境变化之前必须重启)。
你可以为你的应用程序的不同配置文件创建多个不同的启动配置,包括它们需要的其他环境变量。
警告
环境变量存储在 launchSettings.json 不是安全的,并且将作为你的应用程序源代码仓库的一部分,如果你使用其中一个。 坚决不要在这个文件里存储证书或其他安全数据。 如果你需要一个地方来存储这些数据,使用 Safe storage of app secrets during development 里描述的 Secret Manager 工具。
预演
按照惯例, Staging
环境是用于部署到生产环境前进行最后测试的预生产环境。理想的情况下,它的物理特征应该是生产环境的真实写照,因此生产环境中可能出现的任何问题都首先发生在预演环境中,在这里可以解决它们而不影响到用户。
生产
Production
环境是应用程序运行的环境,它是活动的并且被终端用户使用。这个环境应该被配置为最大限度提高安全性,性能和应用程序的健壮性。生产环境不同于开发环境的一些通用的设置包括:
- 启用缓存
- 确保所有的客户端资源被打包,压缩和尽可能从CDN提供
- 关闭诊断错误页面
- 启用友好的错误页面
- 启用生产日志和监控 (例如:Application Insights)
这并不是一个完整的列表。最好避免在你的应用程序各个部分散乱的环境检查。相反,推荐的方式是尽可能在应用程序的 Startup
类中进行这样的检查。
在运行时确定环境
IHostingEnvironment 服务为工作环境提供了核心抽象。该服务由 ASP.NET 宿主层提供,并且能够通过Dependency Injection 注入到你的启动逻辑中。在 Visual Studio 中的 ASP.NET Core 网站模板使用这种方式来加载特定的环境配置文件(如果存在的话)并且自定义应用程序的错误处理设置。在这两种情况下,这种行为是由通过参照当前指定的环境来调用 IHostingEnvironment 的实例上的 EnvironmentName 或IsEnvironment 上传递到适当的方法来实现。
注意
如果你需要检查该应用程序是否在特定环境中运行,使用env.IsEnvironment("environmentname")
因为它会正确的忽略大小写(而不是检查例如env.EnvironmentName == "Development"
)。
例如,你可以使用如下代码在你的配置方法中设置特定环境的错误处理:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
// ...
如果应用程序运行在 Development
环境中,那么它在 Visual Studio 中开启必要运行时支持来使用浏览器链接(BrowserLink)功能,特定的开发错误页面(这通常不应该在生产中运行)和特定的数据库错误页面(它提供了一种应用迁移的方法,因此应该仅在开发中使用)。另外的,如果应用程序不是在开发环境中运行,配置一个标准的错误处理页面来显示响应中的任何未处理异常。
你可能需要在运行时确定需要向客户端发送哪些内容。例如,在开发环境中你通常提供非最小化的脚本和样式表,这更容易调试。在生产和测试环境一般应当从 CND 提供最小化的版本。你可以使用环境 tag helper做到这一点。如果当然环境与使用 names
特性指定的环境相匹配,环境 tag helper 将只提供它的内容。
<environment names="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
在你的应用程序开始使用 tag helpers 查看 tag helper。
启动约定
ASP.NET Core 支持一种基于约定的方法来根据当前环境配置应用程序的启动。依据你的应用程序在哪一种环境,你也可以使用编程的方式控制应用程序的行为,允许你创建和管理你自己的约定。
当 ASP.NET Core 应用程序启动, Startup
类用来引导应用程序,加载其配置设置等(学习更多关于ASP.NET startup)。然而,如果一个类的命名存在 Startup{EnvironmentName}
(例如 StartupDevelopment
),并且 Hosting:Environment
环境变量和它的名称相匹配,那么则使用那个 Startup
类。
除了使用一个基于当前环境的完全独立的启动类,你也可以在 Startup
类中对应用程序如何配置做出调整。Configure()
和 ConfigureServices()
方法类似 Startup
类,以 Configure[EnvironmentName]()
和 Configure[EnvironmentName]Services()
的形式支持特定环境的版本。当设置为开发环境时,如果你定义一个 ConfigureDevelopment()
方法,将调用这个方法而不是 Configure()
。同样,在相同的环境里将调用 ConfigureDevelopmentServices()
而不是 ConfigureServices()
。
概要
ASP.NET Core 提供了许多功能和约定来允许开发者更容易的控制在不同的环境中他们的应用程序的行为。当发布一个应用程序从开发到预演再到生产,为环境设置适当的环境变量允许对应用程序的调试,测试或生产使用进行适当的优化。