学习如何在本地和 Azure 中使用和管理 .NET Core 中的功能标志
功能开关是一种通过开关来启用或禁用功能的概念。为什么要这样做呢?
以下是一些很好的理由:
- 早期集成。通常情况下,你会在分支上开发功能。功能开发耗时越长,完成后合并/变基操作就会越麻烦。如果能尽早将功能集成到主分支,就能减少这类麻烦。这样做的好处是,你可以在功能尚未完全准备好公开使用之前就将其部署到生产环境。这种部署方式也称为暗部署。
- A/B 测试。A/B 测试是一种常用的测试新功能或更改功能的模式。在 A/B 测试中,你需要回答一个问题:A 版本是否优于 B 版本?A 代表应用的一个版本,B 代表另一个版本。为了找到答案,你需要创建应用的不同版本。然后,你可以筛选用户流量,让不同的用户访问不同的版本。之后,你可以衡量各种指标,例如转化率(如果你是电商平台),或者衡量点击特定按钮的用户数量等等。创建网站不同版本的一种方法是确保不同的功能被激活。在网站上,这可以通过在localStorage中设置不同的标志、在 URL 中使用参数或通过后端数据来确定。
- 试运行。试运行是指将新功能分批推送给一定比例的用户。其原理与 A/B 测试非常相似。A/B 测试旨在验证 A 是否优于 B,而试运行则是将新功能推送给一部分用户,观察他们能否顺利使用。如果出现问题,可以随时回滚。
参考
使用功能标志
根据您开发的是移动应用、Web 应用还是其他类型的软件,功能开关的实现方式可能会有所不同。不过,功能开关的应用流程大致相同:
- 创建标志。使用合适的名称和命名空间创建标志,并为其赋值。
- 评估标志的值。这意味着某处有一行代码大致如下所示:
if (flag) {
// render A, else B
}
类似的代码可能已经内置到标签组件中,所以你可能不需要自己编写。(在 .NET Core 中就是这样。)
- 呈现不同的用户体验。由于上一点所述,最终你会做出不同的操作,例如渲染/不渲染页面的某个部分,或者从一个路由重定向到另一个路由等等。具体细节取决于你,但步骤相同。
无需重新编译,无需重新部署
上图是尚格·云顿在电影《不退缩,不投降》中的剧照。击败反派(云顿)的唯一方法是运用高超的武术技巧,而这技巧是由李小龙的亡灵传授给一位年轻武者的。你或许没有亡灵相助,但你可以确保功能标志的管理过程尽可能减少中断——无需重新编译,无需重新部署。
你可以将标志位作为代码中的一个变量。根据该变量的设置,该功能要么开启,要么关闭。但这有一个缺点:它迫使你修改代码、重新编译并重新部署。虽然这有时也能满足你的需求,但很多时候你需要不同的行为,你希望能够在不编译或重新部署的情况下启用/禁用标志位。那么该如何实现呢?你需要将管理标志位的机制移出源代码。有两种方法可以做到这一点,我们将探讨这两种方法:
-
配置文件。通过在配置文件中指定标志及其值,并让你的应用程序从该文件中读取,即可实现标志管理和应用程序的解耦。
-
配置服务。配置服务是一个服务端点,可通过例如 HTTP 请求访问。此类服务可以部署在公司内部网络或云端。
接下来,我们将探讨如何使用上述两种方法在 .NET Core 中实现功能标志。
.NET Core 应用示例
您可以使用 ASP.NET Core 内置的功能在本地处理功能标志,该功能使用名为appsettings.json的 JSON 文件。通过该 JSON 文件,您可以定义要使用的标志及其值。然后,您可以利用 Razor 中的装饰器和内置标签,根据标志的值显示不同的内容。
首先,您将尝试使用配置文件方案,然后再转而使用 Azure 中的应用配置存储。
创建标志并配置您的项目以使用它们。
- 使用以下命令创建 ASP.NET Core 项目:
dotnet new mvc --no-https --output TestFeatureFlags
该命令将在子目录中创建一个 MVC 项目TestFeatureFlags。
- 进入您的项目:
cd TestFeatureFlags
- 使用以下命令添加以下 NuGet 包:
dotnet add package Microsoft.Azure.AppConfiguration.AspNetCore
dotnet add package Microsoft.FeatureManagement.AspNetCore
- 找到
Startup.cs并添加以下 using 语句到代码顶部:
using Microsoft.FeatureManagement;
- 在同一文件中,找到
ConfigureServices()方法并添加行:
services.AddFeatureManagement();
- 在同一文件中,找到
Configure()并添加以下行:
app.UseAzureAppConfiguration();
- 默认情况下,.NET Core 会从appsettings.json
FeatureManagement配置文件的某个部分读取配置。您可以通过在方法中指定自己的名称来覆盖此设置,如下所示:ConfigureService()
services.AddFeatureManagement(options =>
{
options.UseConfiguration(Configuration.GetSection("MyFeatureFlags"));
});
是否进行此更改取决于您,但我们将继续使用默认设置,因此我们需要在appsetting.jsonFeatureManagement中指定一个部分。
- 打开appsetting.json 文件,并添加以下 JSON 配置:
"FeatureManagement": {
"FeatureA": true,
"Beta": true,
"FeatureB": false,
"FeatureC": {
"EnabledFor": [
{
"Name": "Percentage",
"Parameters": {
"Value": 50
}
}
]
}
}
上面,您介绍了特征FeatureA、Beta和FeatureB。FeatureC请注意是如何FeatureC嵌套的。
渲染内容
接下来,您将看到如何使用 Razor 标签feature,并在启用正确的标志后渲染一部分内容。
- 找到名为Index.cshtml 的
Views/Home文件。在文件顶部添加以下行:
@addTagHelper *, Microsoft.FeatureManagement.AspNetCore
这行代码可以让你使用feature标签。
- 在同一文件中,将 HTML 内容更改为以下文本:
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
<feature name="Beta">
<div class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Beta" asp-action="Index">Beta</a>
</div>
</feature>
</div>
请注意上面标签的用法feature:
<feature name="Beta">
<div class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Beta" asp-action="Index">Beta</a>
</div>
</feature>
你的意思是,如果标志位Beta设置为 true true,则渲染这部分内容。查看你的appsettings.json 文件,可以看到标志位Beta已设置为 true true,所以应该可以正常工作。接下来我们构建并运行项目。
- 运行以下命令来构建并运行您的项目:
dotnet build && dotnet run
您会看到类似以下的输出:
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
- 打开浏览器并访问
http://localhost:5000。您应该会看到以下内容:
- 接下来,打开appsetting.json文件,并将该
Beta标志设置为 false,如下所示:
"Beta": true
保存文件并刷新浏览器。现在您应该看到以下内容:
恭喜!您已成功在本地设置功能标志,并通过appsetting.json文件控制其使用。但是,如果您的应用部署到 Azure 等云服务,那么进入部署文件,打开文件并保存就显得不太方便了。我的意思是,虽然可以这样做,但感觉很笨拙,更糟糕的是,在本地修改文件后重新部署整个应用,真是太麻烦了!
更好的方法是依赖配置服务。对于 Azure,您可以使用名为Azure 配置存储的服务。接下来,我们将利用这项服务。
添加 Azure 配置存储
在添加云服务之前,请先回顾一下我们即将采取的步骤:
-
设置密钥存储。在开发过程中,迁移配置和密钥的一个好方法是使用密钥存储。密钥存储是一个将密钥与特定 .NET Core 项目关联的工具。但是,如果将应用迁移到云端,则需要使用“应用配置”选项卡来存放密钥,或者更好的选择是使用 Azure Key Vault。
-
配置 Azure 配置存储。配置配置存储非常简单。在这里,我们将配置存储并添加一个功能标志,该标志将与appsettings.json中的内容相对应。
-
配置应用以使用配置存储。最后,我们将配置应用以使用配置存储。这只需指定配置存储的连接字符串并编写一行配置代码即可。
设置密钥存储
- 要设置密钥存储,请运行以下命令
dotnet user-secrets init:
dotnet user-secrets init
现在你的项目文件中多了一个以.csproj结尾的新条目,类似于这样:
<UserSecretsId>9dcd0c7b-e32d-407d-aabd-d34c644ecaaf</UserSecretsId>
我们将在需要从云资源中持久化连接字符串时再讨论密钥管理。
预配 Azure 配置存储
-
要配置一个
Azure Config Store,请前往portal.azure.com。 -
从左上角菜单中选择“创建资源” 。
-
在“搜索应用市场”框中,输入“应用配置”并选择
Enter。 -
从搜索结果中选择“应用程序配置”,然后选择“创建”。
-
在“创建应用程序配置”窗格中,输入以下设置:
- 选择“审核+创建”以验证您的设置。
- 选择创建
获取连接字符串
资源配置完成后,请前往资源页面。
-
选择“设置”>“快捷键”。
-
记下主只读密钥连接字符串。
创建功能标志
-
选择操作 > 功能管理器 > 添加。
-
在“添加”窗格中:
- 检查启用功能标志
- 在“功能标志名称”中,输入“Beta”。
- 选择“应用”以创建功能标志
配置应用程序以使用配置存储
- 在终端中,进入项目根目录,运行
dotnet user-secrets set":
请确保将“<您的连接字符串>”替换为您在 Azure 门户中记下的连接字符串。
dotnet user-secrets set ConnectionStrings:AppConfig "<your_connection_string>"
这会在密钥管理器中设置一个密钥,您接下来可以通过代码检索该密钥。
- 打开Startup.cs 文件,找到该
Configure()方法并添加以下行:
app.UseAzureAppConfiguration();
- 在同一文件中,找到
ConfigureServices()并添加以下行:
services.AddAzureAppConfiguration();
- 打开Program.cs文件,找到该方法
CreateHostBuilder()并将其替换为以下代码:
public static IHostBuilder CreateHostBuilder(string[] args)
=>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
webBuilder.ConfigureAppConfiguration(config =>
{
var settings = config.Build();
var connection = settings.GetConnectionString("AppConfig");
config.AddAzureAppConfiguration(options =>
options.Connect(connection).UseFeatureFlags());
}).UseStartup<Startup>());
你所做的就是调用实例ConfigureAppConfiguration()上的方法webBuilder。它接受一个委托,你通过该委托从配置节中Action检索值。然后,你使用返回的字符串值调用连接到配置存储并指示其使用功能标志的方法。接下来,让我们重新构建并运行你的应用程序,看看它是否有效 :)AppConfigConnectingStringsAddAzureAppConfiguration()
- 使用以下终端命令运行应用程序:
dotnet build && dotnet run
现在你应该能看到你的应用渲染成这样:
这次,功能标志值是从 Azure 读取的,而不是从appsettings.json读取的。
-
让我们取消勾选该标志:
- 返回 Azure 门户和应用配置资源页面:
- 选择“操作”>“功能管理器”
- 取消勾选Beta功能标志的复选框。
- 运行
Ctrl-C以下命令重启应用程序dotnet run:
这次,你应该会看到如下图片,其中“Beta”字样已消失。
概括
首先,你了解了什么是功能标志以及它们在哪些场景下适用。然后,你了解了一些关于范·达姆的冷知识,不好意思啦 ;) 。之后,你学习了如何使用appsettings.json文件在本地设置功能标志。最后,你学习了如何使用 Azure 应用配置服务,不仅可以存储功能标志,还可以从应用中读取它们的值。希望这能让你对使用应用配置服务更感兴趣,因为还有更多内容值得学习 :)
文章来源:https://dev.to/azure/no-recompile-no-redeploy-managing-features-flags-in-net-core-locally-and-with-azure-5h84





