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

img

寫在前面

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,

可以看到:

image-20220804104253051

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

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

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

我們來測測:

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 配置中心後臺配置好功能開關(代替本地配置文件)

基本功能開關配置

創建配置:

image-20220804115402160

填寫配置信息:

image-20220804122451808

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

image-20220804123400869

基於過濾器的開關配置

百分率功能開關

image-20220804123721457

時間窗口功能開關

image-20220804123801220

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

自定義功能開關

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章