微软Azure配置中心 App Configuration (二):Feature Flag 功能开关特性

写在前面
Web服务开发过程中我们经常有这样的需求:
- 某些功能我必须我修改了配置才启用,比如新用户注册送券等;
- 某个功能需到特定的时间才启用,过后就失效,比如春节活动等;
- 某些功能,我想先对10%的用户开放,验证没问题后再逐步全量开放等;
这就是功能开关。
日常开发中功能开关我们一般是写到配置文件里的,根据不同的配置,做不同的逻辑;但,其实.net core是对功能开关有官方支持的,但因为跟Azure集成比较好所以文档不在.net core的文档里面,而是在Azure的文档这边:
https://docs.microsoft.com/en-us/azure/azure-app-configuration/
Asp.net Core中集成
Asp.net Core的功能开关(Feature Flag)是直接仅根据配置文件方式使用,和集成Azure配置中心使用的;我们来看看区别;
本地配置文件方式
1、先安装包
install-package Microsoft.FeatureManagement.AspNetCore
2、注入服务(net6)
builder.Services.AddFeatureManagement();
3、配置文件写几个配置
appsettings.json
"FeatureManagement": {
//简单功能开关
"Beta": true,
"v1": true,
"v2": true,
}
以上配置对应以下的枚举:
public enum MyFeatureFlags
{
Beta,
V1,
V2,
PercentageFlag,
TimeWindowFlag,
CustomFeatureFlag
}
其实不用枚举,直接用字符串也是可以的;
4、使用功能开关
1、创建一个FeatureFlagController;
注入服务:
private readonly IFeatureManager _featureManager;
public FeatureFlagController(IFeatureManager featureManager)
{
_featureManager = featureManager;
}
简单功能开关:
/// <summary>
/// 当启用beta版本的时候接口有效
/// </summary>
/// <returns></returns>
[FeatureGate(MyFeatureFlags.Beta)]
[HttpGet]
public async Task<IActionResult> Beta()
{
var beta = await _featureManager.IsEnabledAsync(nameof(MyFeatureFlags.Beta));
if (beta)
{
//beta版本特有逻辑
}
return Success("Beta", beta); //这里Success是封装的,大家可以改成返回Ok()
}
/// <summary>
/// 当启用v1版本的时候接口有效
/// </summary>
/// <returns></returns>
[FeatureGate(MyFeatureFlags.V1)]
[HttpGet]
public async Task<IActionResult> V1()
{
return Success("V1");
}
/// <summary>
/// 当启用v2版本的时候接口有效
/// </summary>
/// <returns></returns>
[FeatureGate(MyFeatureFlags.V2)]
[HttpGet]
public async Task<IActionResult> V2()
{
return Success("V2");
}
由于我们上面的配置都是开启的:
...
//简单功能开关
"Beta": true,
"v1": true,
"v2": true,
可以看到:

接口都可以访问,我们把v1改成false试试:

马上404了,这里清晰的看到,功能开关在多版本Api上线下某个版本时候确实方便;
基于过滤器的功能开关:
基于过滤器的功能开关是有一定逻辑的功能开关;
a、百分率功能开关
/// <summary>
/// 启用百分率的功能开关
/// </summary>
/// <returns></returns>
[FeatureGate(MyFeatureFlags.PercentageFlag)]
[HttpGet]
public async Task<IActionResult> PercentageFlag()
{
return Success("PercentageFlag");
}
builder.Services.AddFeatureManagement()
.AddFeatureFilter<PercentageFilter>();
添加配置:
FeatureManagement节点下:
//百分率功能开关
"PercentageFlag": {
"EnabledFor": [
{
"Name": "Percentage",
"Parameters": {
"Value": 30
}
}
]
},
这里的配置参数值代表30%的概率启用次功能,我们试试:

分别是不启用,和启用状态;
b、时间窗口功能开关
/// <summary>
/// 启用时间窗口的功能开关
/// </summary>
/// <returns></returns>
[FeatureGate(MyFeatureFlags.TimeWindowFlag)]
[HttpGet]
public async Task<IActionResult> TimeWindowFlag()
{
return Success("TimeWindowFlag");
}
builder.Services.AddFeatureManagement()
.AddFeatureFilter<TimeWindowFilter>();
添加配置:
//时间窗口功能开关
"TimeWindowFlag": {
"EnabledFor": [
{
"Name": "TimeWindow",
"Parameters": {
"Start": "2022/08/03 08:00:00 +00:00", //这里是UTC时间
"End": "2022/08/03 09:00:00 +00:00"
}
}
]
},
这个开关在2022年8月3日 下午16时(北京时间)和17时这个世界窗口内才启用;对应的:
Start:就是生效时刻;
End:失效时刻;
c、自定义功能开关
ok,以上都是系统内置的功能开关,我们来根据自己需求创建一个自定义的;
需求:某个功能只有在客户端是手机或者平板的情况下启用,pc端不启用;
创建一个自定义功能开关过滤器类CustomFeatureFilter
[FilterAlias("CustomFeature")]
public class CustomFeatureFilter : IFeatureFilter
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CustomFeatureFilter(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
{
//这里参数模拟平台,实际业务会有实际业务的逻辑
var platform = _httpContextAccessor.HttpContext.Request.Query["platform"].ToString();
var allowPlatform = context.Parameters.Get<CustomFeatureFilterSettings>();
return Task.FromResult(allowPlatform.AllowedPlatforms.Any(c => c == platform));
}
}
public class CustomFeatureFilterSettings
{
public string[] AllowedPlatforms { get; set; }
}
/// <summary>
/// 自定义功能开关
/// </summary>
/// <returns></returns>
[FeatureGate(MyFeatureFlags.CustomFeatureFlag)]
[HttpGet]
public async Task<IActionResult> CustomFeatureFlag(string platform)
{
return Success("CustomFeatureFlag");
}
builder.Services.AddFeatureManagement()
.AddFeatureFilter<CustomFeatureFilter>();
添加配置:
//自定义功能开关
"CustomFeatureFlag": {
"EnabledFor": [
{
"Name": "CustomFeature",
"Parameters": {
"AllowedPlatforms": [ //这里配置运行启用功能的平台
"phone",
"pad"
//"pc"
]
}
}
]
}
我们来测测:

可以看到仅在设置运行的平台下启用,验证ok;
集成Azure配置中心App Configuration方式
1、添加配置:
"ConnectionStrings": {
"AppConfig": "<your app connection string>"
},
具体可参考我之前的文章:《微软Azure配置中心 App Configuration (一):轻松集成到Asp.Net Core》
2、启用Azure功能开关:
var connectionString = builder.Configuration.GetConnectionString("AppConfig");
builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
//配置不同功能
config.AddAzureAppConfiguration(options =>
{
////启用功能开关特性
options.Connect(connectionString)
//启用功能开关特性
.UseFeatureFlags(options =>
{
options.CacheExpirationInterval = TimeSpan.FromSeconds(30); //配置FeatureFlag缓存本地时间(默认就是30)
});
});
});
UseFeatureFlags启用后,本地配置文件的方式失效;
builder.Services.AddAzureAppConfiguration(); //注入服务
3、在Azure 配置中心后台配置好功能开关(代替本地配置文件)
基本功能开关配置
创建配置:

填写配置信息:

OK,以上是基本的配置,配置好后可以直接在列表页面勾选启用配置与否:

基于过滤器的开关配置
百分率功能开关

时间窗口功能开关

这里的Start date,和Expiry date,就对应前面配置文件的Start,End;
自定义功能开关

这里的过滤器的Name:CustomFeature ,要跟代码标签 [FilterAlias("CustomFeature")]一致;
AllowedPlatforms:也要跟代码里面的配置一致,["phone","pad"]这个是数组的写法;
总结
1、启用集成到Azure的UseFeatureFlags后,本地配置文件的方式失效;
2、Azure这套功能开关还是有可选之处的,我尤其喜欢其接口标签[FeatureGate];
另外定义了的标准配置项,与Azure配置中心无缝集成,香。
源码
https://github.com/gebiWangshushu/Hei.Azure.Test
[参考]
https://docs.microsoft.com/en-us/azure/azure-app-configuration/overview
微软Azure配置中心 App Configuration (二):Feature Flag 功能开关特性的更多相关文章
- 微软Azure配置中心 App Configuration (三):配置的动态更新
写在前面 我在前文: <微软Azure配置中心 App Configuration (一):轻松集成到Asp.Net Core>已经介绍了Asp.net Core怎么轻易的接入azure ...
- 微软Azure配置中心 App Configuration (一):轻松集成到Asp.Net Core
写在前面 在日常开发中,我这边比较熟悉的配置中心有,携程Apollo,阿里Nacos(配置中心,服务治理一体) 之前文章: Asp.Net Core与携程阿波罗(Apollo)的第一次亲密接触 总体来 ...
- 七、springcloud之配置中心Config(二)之高可用集群
方案一:传统作法(不推荐) 服务端负载均衡 将所有的Config Server都指向同一个Git仓库,这样所有的配置内容就通过统一的共享文件系统来维护,而客户端在指定Config Server位置时, ...
- 微软Azure通知中心 (Azure Notification Hubs)
Azure Notification Hubs 提供简单的方法从后台(azure或者on-promise)去发送通知在不同的平台上面(iOS, Android, Windows, Kindle, Ba ...
- 分布式配置中心介绍--Spring Cloud学习第六天(非原创)
文章大纲 一.分布式配置中心是什么二.配置基本实现三.Spring Cloud Config服务端配置细节(一)四.Spring Cloud Config服务端配置细节(二)五.Spring Clou ...
- springcloud学习之路: (五) springcloud集成SpringCloudConfig分布式配置中心
SpringCloud全家桶中的分布式配置中心SpringCloudConfig, 它使用git来管理配置文件, 在修改配置文件后只需要调用一个接口就可以让新配置生效, 非常方便. SpringClo ...
- 撸了一个简易的配置中心,顺带整合到了SpringCloud
大家好,我是三友~~ 最近突然心血来潮(就是闲的)就想着撸一个简单的配置中心,顺便也照葫芦画瓢给整合到SpringCloud. 本文大纲 配置中心的概述 随着历史的车轮不断的前进,技术不断的进步,单体 ...
- 配置中心之Nacos简介,使用及Go简单集成
简介 为什么需要配置中心 我们现在有一个项目, 使用Gin进行开发的, 配置文件我们知道是一个config.yaml的文件, 也知道这个配置文件在项目启动时会被加载到内存中使用; 考虑三种情况: ...
- 给你的 ASP.NET Core 程序插上 Feature Flag 的翅膀
前言 我们知道,目前大多数应用程序在正式发布到生产环境之前都会经历多个不同的测试环境,通过让应用程序在多个不同的环境中运行来及时发现并解决问题,避免在线上发生不必要的损失.这是对于整个软件的发布流程来 ...
随机推荐
- 用C语言实现井字棋(人人/AI人机)--完结版
目录 用C语言实现井字棋(人人/AI人机)--完结版 BUG与优化3: 1. 修改了step的计算方法,每个玩家玩完就加一次step 2. 改变了电脑下棋的逻辑,每个玩家玩完之后都跳过这次循环 源码: ...
- Linux系统sed命令常用参数实战
Linux系统sed命令常用参数实战 常用参数 -n 输出某行的文本内容,通常与p联合使用, -e 命令行模式下进行sed的动作编辑,输出编辑后的内容,源文件不会发生变化 -f 以命令中指定的scri ...
- 开源流程引擎osworkflow、jbpm、activiti、flowable、camunda哪个好?
市场上比较有名的开源流程引擎有osworkflow.jbpm.activiti.flowable.camunda.其中:Jbpm4.Activiti.Flowable.camunda四个框架同宗同源, ...
- 推荐一款M1芯片电脑快速搭建集群的虚拟机软件
虚拟机软件太多了,出名的莫过于VMware,VirutlaBox以及Parallels Desktop. 我们使用虚拟机软件一般有两种用途: 安装不同于宿主机系统的拥有用户界面的操作系统,比如Wind ...
- linux-python安装pip
wget https://bootstrap.pypa.io/get-pip.py --no-check-certificate sudo python3 get-pip.py linux 建立软连接 ...
- Linux IO重定向和管道
计算机组成部分: 由io . 控制器.计算器.存储器组成 IO: input output 计算机里面通过终端窗口实现输入和输出,键盘鼠标屏幕这些只是手段,真正完成输入输出的是终端窗口 标准输入.出. ...
- .Net下极限生产力之efcore分表分库全自动化迁移CodeFirst
.Net下极限生产力之分表分库全自动化Migrations Code-First ## 介绍 本文ShardinfCore版本x.6.x.x+ 本期主角: - [`ShardingCore`](htt ...
- Tapdata肖贝贝:实时数据引擎系列(三) - 流处理引擎对比
摘要:本文将选取市面上一些流计算框架包括 Flink .Spark .Hazelcast,从场景需求出发,在核心功能.资源与性能.用户体验.框架完整性.维护性等方面展开分析和测评,剖析实时数据框架 ...
- 函数式(Functional)接口
public class LambdaTest2 { @Test public void test1(){ happyTime(500, new Consumer<Double>() { ...
- 基于ABP实现DDD--DDD相关概念
什么是DDD呢?领域驱动设计[DDD]是一种针对复杂需求的软件开发方法.将软件实现与不断发展的模型联系起来,专注于核心领域逻辑,而不是基础设施细节.DDD适用于复杂领域和大规模应用,而不是简单的C ...