配置中心 App Configuration (二):Feature Flag 功能開關特性

94d513530675a43057dcda8376f9f054.png


寫在前面

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,

可以看到:

c95cd7eb11eb81c354fa9594cd632d1b.png
image-20220804104253051

接口都可以訪問,我們把v1改成false試試:

f2560d077337208c87cb231679268d6c.png
image-20220804104401620

馬上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%的概率啟用次功能,我們試試:

578e62500574e6d07ed99536b4b1c4ed.png
image-20220804105858780

分別是不啟用,和啟用狀態;

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"]}}]
}

我們來測測:

d08601fd1319df08e46d7f024b8935e7.png
image-20220804111012239

可以看到僅在設置運行的平臺下啟用,驗證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 配置中心后臺配置好功能開關(代替本地配置文件)

基本功能開關配置

創建配置:

4b707dce557130ffa58431a41fbe1188.png
image-20220804115402160

填寫配置信息:

7db79b7961af2fe1421d8ca9ed84b79a.png
image-20220804122451808

OK,以上是基本的配置,配置好后可以直接在列表頁面勾選啟用配置與否:

4e6c45bdde1591d4f36f102d431b6ab7.png
image-20220804123400869

基于過濾器的開關配置

百分率功能開關

0e8f7cfd3aa435ed7301ab1ebfd2b256.png
image-20220804123721457

時間窗口功能開關

66bea77aa4cde4c3e2937f261b7a800f.png
image-20220804123801220

這里的Start date,和Expiry date,就對應前面配置文件的Start,End;

自定義功能開關

74fd1916694f69c685b0bd9ecb43d01f.png
image-20220804123835703

這里的過濾器的**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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/283754.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/283754.shtml
英文地址,請注明出處:http://en.pswp.cn/news/283754.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

oracle臨時表空間

--查看臨時表空間SELECT * FROM v$tablespace;SELECT * FROM dba_tablespaces;--查看所有臨時表空間文件SELECT * FROM dba_data_files;--查看臨時臨時表空間文件SELECT * FROM dba_temp_files;--查看臨時表空間組SELECT * FROM dba_tablespace_groups; --查找默認臨時表空間SE…

ES 2022 正式發布!有哪些新特性?

2022 年 6 月 22 日&#xff0c;第 123 屆 Ecma 大會批準了 ECMAScript 2022 語言規范[1]&#xff0c;這意味著它現在正式成為標準。 1 ECMAScript 2022編輯 本次發布的編輯有&#xff1a; Shu-yu Guo[2] Michael Ficarra[3] Kevin Gibbons[4] 2 ECMAScript 2022有什么新內…

聯想(Lenovo)小新310經典版進bios方法

1&#xff0c;找到novo按鈕。 2&#xff0c;在關機的狀態下桶一下小孔&#xff0c;不用任何操作&#xff0c;電腦進入bios選擇界面。轉載于:https://www.cnblogs.com/senior-engineer/p/6761457.html

C#中的匿名類型

這節來講一下C#中的匿名類型。匿名類在C#中&#xff0c;我們可以不去顯示的聲明一個類&#xff0c;而是通過匿名類去臨時聲明一個類結構去幫助我們去完成一些功能。聲明一個匿名類&#xff0c;我們可以像下面這樣做&#xff1a;var Anonymousnew {name"charles",year…

MySQL之MHA高可用集群

目錄 一、MHA概述 1.1.MHA 是什么 1.2.MHA 的組成 1.3.MHA 的特點 二、MHA搭建準備 2.1.實驗思路 三、MHA搭建 3.1配置主從復制 3.2.安裝 MHA 軟件 3.3.故障模擬 3.4.故障修復 四、總結 一、MHA概述 1.1.MHA 是什么 1.MHA&#xff08;MasterHigh Availability&…

Tensorflow之安裝

1.fellow the instruction of https://www.tensorflow.org/install/install_linux#installing_with_anaconda 2.anaconda安裝&#xff0c;修改~/.bash_profile為 export PATH~/anaconda2/bin:/usr/local/cuda/bin:$PATHexport LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRAR…

2、Saltstack的數據系統

一、Grainsgrains是salt用來收集minion端底層系統信息的接口。比如&#xff0c;操作系統type、域名 、IP地址、內存及其他相關系統屬性信息等。存儲在minion端&#xff0c;用于保存minion端數據信息。minion啟動時才加載grains信息&#xff0c;所以他時靜態的&#xff0c;Grain…

配置中心 App Configuration (一):輕松集成到Asp.Net Core

寫在前面在日常開發中&#xff0c;我這邊比較熟悉的配置中心有&#xff0c;攜程Apollo&#xff0c;阿里Nacos(配置中心&#xff0c;服務治理一體)之前文章&#xff1a;Asp.Net Core與攜程阿波羅(Apollo)的第一次親密接觸總體來說&#xff0c;Apollo和Nacos社區都比較活躍&#…

stop-hbase.sh一直處于等待狀態

今天關閉HBase時&#xff0c;輸入stop-hbase.sh一直處于等待狀態 解決方法&#xff1a; 先輸入&#xff1a;hbase-daemon.sh stop master 再輸入&#xff1a;stop-hbase.sh就可以關閉HBase集群了。 轉載于:https://www.cnblogs.com/lijinze-tsinghua/p/8667761.html

shell編程100例

1、編寫hello world腳本 #!/bin/bash# 編寫hello world腳本echo "Hello World!"2、通過位置變量創建 Linux 系統賬戶及密碼 #!/bin/bash# 通過位置變量創建 Linux 系統賬戶及密碼#$1 是執行腳本的第一個參數,$2 是執行腳本的第二個參數 useradd "$1" …

sqlserver 分頁

select top 10 numComImg.* from( select row_number() over(order by id asc) as rownumber,* from (select * FROM [TCCLine].[dbo].[CLine_CommonImage]) as comImg)as numComImg where rownumber>40select top 10 * --10 為頁大小from [TCCLine].[dbo].[CLine_CommonIma…

詳解SpringMVC中Controller的方法中參數的工作原理[附帶源碼分析] good

目錄 前言現象源碼分析 HandlerMethodArgumentResolver與HandlerMethodReturnValueHandler接口介紹HandlerMethodArgumentResolver與HandlerMethodReturnValueHandler接口的具體應用常用HandlerMethodArgumentResolver介紹常用HandlerMethodReturnValueHandler介紹本文開頭現象…

instancing render

當要繪制同一個東西很多次的時候&#xff0c;最簡單的想法可能是循環調用glDrawArrays()&#xff0c;但這樣會造成性能的損失。因為當顯卡在渲染一個物體的時候&#xff0c;可能并不需要太多時間&#xff0c;但系統會花大量的時間&#xff0c;頻繁的調用draw命令&#xff0c;再…

對不起,我不是一個自律的人

大家好&#xff0c;我是 &#x1f41f;&#x1f4a8;。前天&#xff0c;星球 的一位大學生朋友問了我幾個問題&#xff1a;你大學時如何安排每日的時間&#xff1f;為什么能學那么多技術&#xff1f;你會學習到很晚嗎&#xff1f;你是如何保持自律的&#xff1f;我覺得這幾個問…

保證接口數據安全的10種方案

前言 大家好&#xff0c;我是程序汪&#xff0c;互聯網項目需要特別注意數據安全&#xff0c;如果你簡歷上是互聯網類型項目&#xff0c;安全方面肯定要能說出個一二三&#xff0c;下面分享下這方面的干貨&#xff0c;大家可以記住幾條&#xff0c;面試時好說道說道 我們日常…

Html5本地存儲LocalStorage

HTML5 提供了兩種在客戶端存儲數據的新方法&#xff1a; localStorage - 沒有時間限制的數據存儲sessionStorage - 針對一個 session 的數據存儲在瀏覽器中打開審查元素&#xff08;如谷歌F12&#xff09;&#xff0c;在Resources下面可以查看里面的數據。 localStorage提供了幾…

python 中的os模塊

python os模塊 Python os 模塊提供了一個統一的操作系統接口函數一、對于系統的操作1、os.name 當前使用平臺其中 ‘nt’ 是 windows&#xff0c;’posix’ 是linux 或者 unix2、os.sep輸出操作系統的特定的路徑分隔符。Win下為“\”&#xff0c;Linux下為“/”3、os.pathsep 輸…

java第一季2.2

2019獨角獸企業重金招聘Python工程師標準>>> 標識符&#xff1a; 是給變量類方法命名的符號、標識符開頭可以_、字母、$命名&#xff0c;不可以用數字命名。關鍵字不可命名&#xff0c;大小寫區分。不可以用非法字符 變量&#xff1a;變量類型。變量名。變量值。如&…

讀《華為數字化轉型之道》

數字化轉型應該很多人都聽過&#xff0c;但如果你做過 ToB 軟件&#xff0c;聽得更多的是信息化&#xff0c;那信息化和數字化是什么關系呢&#xff1f;下面用一個小例子來說說我的理解。記得剛上初中的時候&#xff0c;平時測驗、考試的試卷&#xff0c;都是人工在板上進行刻寫…

Thrift基本原理及使用

參考文章RPC 基本原理與 Apach Thrift 初體驗 RPC基本原理 RPC(Remote Procedure Call)&#xff0c;遠程過程調用&#xff0c;大部分的RPC框架都遵循如下三個開發步驟&#xff1a; 1. 定義一個接口說明文件&#xff1a;描述了對象(結構體)、對象成員、接口方法等一系列信息&am…