給你的 ASP.NET Core 程式插上 Feature Flag 的翅膀

来源:https://www.cnblogs.com/hippieZhou/archive/2020/01/02/12104710.html
-Advertisement-
Play Games

前言 我們知道,目前大多數應用程式在正式發佈到生產環境之前都會經歷多個不同的測試環境,通過讓應用程式在多個不同的環境中運行來及時發現並解決問題,避免線上上發生不必要的損失。這是對於整個軟體的發佈流程來講。但是如果想讓我們的應用程式線上上環境中通過滿足一些動態條件(比如電商平臺在某一時間段的促銷活動) ...


前言

我們知道,目前大多數應用程式在正式發佈到生產環境之前都會經歷多個不同的測試環境,通過讓應用程式在多個不同的環境中運行來及時發現並解決問題,避免線上上發生不必要的損失。這是對於整個軟體的發佈流程來講。但是如果想讓我們的應用程式線上上環境中通過滿足一些動態條件(比如電商平臺在某一時間段的促銷活動)從而能開啟一些臨時功能的話又該怎麼辦呢?如果你試圖通過重新打包發佈的方式來解決這個問題,可能有些過於大動干戈了。本文,筆者將介紹通過 Feature Flag 的方式來解決這個問題。

正文

Feature Flag 中文可譯為 功能開關。通過使用這種方式,可以對我們的功能進行條件化配置,當程式線上上環境運行時,如果當前環境符合我們某一特性功能開啟/關閉的條件時,應用程式會自動開啟/關閉該功能。整個過程不需要人工參與,全部都是由系統本身來完成相應功能的開啟和關閉。

那在 .NET Core 中,我們該如何實現該功能呢?

微軟為我們很貼心地提供了兩個開發包:Microsoft.FeatureManagementMicrosoft.FeatureManagement.AspNetCore,該實現是基於 .NET Core 的配置系統 ,所以任何 .NET Core 程式都可以輕易集成該功能。

目前還處於預覽版階段,需要在 NuGet 上勾選 use prerelease

因此,我們只需將對應包安裝到我們的應用程式中即可。

接下來,我們就一起看一下如何在 ASP.NET Core 中集成該功能。

使用入門

創建一個 ASP.NET Core Web Application 後,安裝如下包:

Install-Package Microsoft.FeatureManagement.AspNetCore -Version 2.0.0-preview-010610001-1263

接著在 Startup 中的 ConfigureServices 進行相應配置,示例如下:

public void ConfigureServices(IServiceCollection services)
{
    services.AddFeatureManagement();
    services.AddControllersWithViews();
}

至此,我們的程式已經支持 Feature Flag 功能了,使用方式就簡單了,這裡展示一個相對簡單的方式。

首先,在 appsettings.json 進行配置,如下所示:

  "FeatureManagement": {
    "NewFeatureFlag": true,
  }

然後,在 Index.cshtml 通過使用 feature 標簽來進行相應配置,示例如下所示:

@using Microsoft.FeatureManagement
@inject IFeatureManager FeatureManager
@addTagHelper *,Microsoft.FeatureManagement.AspNetCore
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>

    <feature name="NewFeatureFlag" requirement="All">
        <a asp-action="NewFeature">Go to the new feature.</a>
    </feature>
</div>

此時,我們運行起程式後就可以看到 feature 標簽內的內容就可以渲染出來,如果我們在配置中將 NewFeatureFlag 值設置為 False 後,feature 標簽內的內容就會消失,你可以通過查看網頁源碼的方式來查看具體細節。

接下來筆者介紹一下微軟為我們內置的兩個功能開關:

PercentageFilter

PercentageFilter 是支持百分比的隨機開關,通過使用這種方式,可以讓一個功能在每次請求中以一個百分比概率的形式來開啟/關閉。

  • 註入功能開關

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddFeatureManagement()
        .AddFeatureFilter<PercentageFilter>();
    services.AddControllersWithViews();
}
  • 配置功能開關

appsettings.json

  "FeatureManagement": {
    "RandomFlag": {
      "EnabledFor": [
        {
          "Name": "Percentage",
          "Parameters": {
            "Value": 50
          }
        }
      ]
    }
  }

這裡配置的是在每次請求時以 50% 的概率來開啟該功能,其對應的配置類為:PercentageFilterSettings

  • 使用功能開關

Index.cshtml

@using Microsoft.FeatureManagement
@inject IFeatureManager FeatureManager
@addTagHelper *,Microsoft.FeatureManagement.AspNetCore
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>

    <feature name="RandomFlag">
        <h2>I am a Random Flag!</h2>
    </feature>
    
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

這時,當我們運行起程式後就會看到如下圖所示的效果:

TimeWindowFilter

TimeWindowFilter 是時間段的隨機開關,通過使用這種方式,可以讓一個功能在指定的時間段內來開啟/關閉。

  • 註入功能開關

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddFeatureManagement()
        .AddFeatureFilter<TimeWindowFilter>();
    services.AddControllersWithViews();
}
  • 配置功能開關

appsettings.json

  "FeatureManagement": {
    "RandomFlag": {
      "EnabledFor": [
        {
          "Name": "Percentage",
          "Parameters": {
            "Start": "2019/12/27 5:04:00 +00:00",
            "End": "2019/12/27 5:04:05 +00:00"
          }
        }
      ]
    }
  }

這裡需要註意的是,配置裡面的 StartEndDateTimeOffset 類型,並且需要配置為 UTC 的時間,所以在實際使用過程中需要考慮時區問題(你可以通過調用 DateTimeOffset.UtcNow 的方式來獲取相應時間的格式)。其對應的配置類為:TimeWindowFilterSettings

  • 使用功能開關

Index.cshtml

@using Microsoft.FeatureManagement
@inject IFeatureManager FeatureManager
@addTagHelper *,Microsoft.FeatureManagement.AspNetCore
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>

    <feature name="TimedFlag">
        <h2>I am a Timed Flag!</h2>
    </feature>
    <p>@DateTimeOffset.UtcNow.ToString()</p>
    
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

這時,當我們運行起程式後就會看到如下圖所示的效果:

自定義功能開關

最後要介紹的是如果創建和使用自定義的功能開關,筆者這裡做一個這樣的示例,當網站被 Microsoft Edge 瀏覽器訪問時,顯示功能,其餘瀏覽器則隱藏功能。

這裡,筆者創建一個配置的映射類 BrowserFilterSettings 和執行過濾的操作類 BrowserFeatureFilter,示例代碼如下所示:

public class BrowserFilterSettings
{
    public string[] AllowedBrowsers { get; set; }
}

[FilterAlias("BrowserFilter")]
public class BrowserFeatureFilter : IFeatureFilter
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public BrowserFeatureFilter(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
    {
        var userAgent = _httpContextAccessor.HttpContext.Request.Headers["User-Agent"].ToString();
        var settings = context.Parameters.Get<BrowserFilterSettings>();
        return Task.FromResult(settings.AllowedBrowsers.Any(userAgent.Contains));
    }
}

接著,進行功能開關的註入,示例代碼如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
    services.AddFeatureManagement()
        .AddFeatureFilter<BrowserFeatureFilter>();
    services.AddControllersWithViews();
}

然後,進行功能開關的配置,示例配置如下所示:

  "FeatureManagement": {
    "BrowserFlag": {
      "EnabledFor": [
        {
          "Name": "BrowserFilter",
          "Parameters": {
            "AllowedBrowsers": [
              "Edge"
            ]
          }
        }
      ]
    }
  }

接著,使用方式如下所示:

@using Microsoft.FeatureManagement
@inject IFeatureManager FeatureManager
@addTagHelper *,Microsoft.FeatureManagement.AspNetCore
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>

    <feature name="BrowserFlag">
        <h2>I am a Browser Flag only on Edge!</h2>
    </feature>
    
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

這時,當我們分別用 Microsoft Edge 和 Google Chrome 訪問站點時就會看到如下圖所示的效果:

總結

藉助於 Microsoft.FeatureManagement.AspNetCore 擴展包,我們可以很容易實現 Feature Flag 效果。又由於這種實現是基於 IConfiguration 的,所以很具有通用性。這裡列出官方給出的優點:

  • A common convention for feature management
  • Low barrier-to-entry
    • Built on IConfiguration
    • Supports JSON file feature flag setup
  • Feature Flag lifetime management
    • Configuration values can change in real-time, feature flags can be consistent across the entire request
  • Simple to Complex Scenarios Covered
    • Toggle on/off features through declarative configuration file
    • Dynamically evaluate state of feature based on call to server
      API extensions for ASP.NET Core and MVC framework
    • Routing
    • Filters
    • Action Attributes

非常感謝你能閱讀這篇文章,希望它能對你有所幫助。

相關參考


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在上面幾篇文章的學習之後,組織管理的新增功能的前端與後臺功能基本實現了我們所要。今天開始我們要通過WebAPI來替換控制器中的操作方法。在學習WebAPI之前,我先來介紹一下Swagger這個組件。 ...
  • 從何說起 這來自於我把項目遷移到Asp.Net Core的過程中碰到一個問題。在一個web程式中同時包含了MVC和WebAPI,現在需要給WebAPI部分單獨添加一個介面驗證過濾器 ,常規做法一般是寫好過濾器後給需要的控制器掛上這個標簽,高級點的做法是註冊一個全局過濾器,這樣可以避免每次手動添加同時 ...
  • 新建類庫,右鍵添加 "文本模板" 添加完成之後生成如下尾碼為 tt的文件: 雙擊文件:TextTemplate_Test.tt 文件打開,替換代碼如下 需要更換幾個配置的地方: 1,設置資料庫連接,找到該段代碼:string connectionString ="Data Source=127.0. ...
  • Spire.Cloud.PDF提供了介面PdfConvertApi可用於將PDF文檔轉換為其他格式文檔,如Word(docx/doc)、Html、XPS、SVG、PCL、PS、Png以及XPS轉成PDF。本文將選取其中幾種格式為例,介紹具體轉換方法。 必要步驟: 步驟一:dll文件獲取及導入。 方法 ...
  • 本筆記摘抄自:https://www.cnblogs.com/skylaugh/archive/2011/07/12/2103572.html,記錄一下學習過程以備後續查用。 數據加密技術是網路中最基本的安全技術,主要是通過對網路中傳輸的信息進行數據加密來保障其安全性,這是一種主動安全防禦策略,用很 ...
  • 原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/25/c-7-series-part-10-spant-and-universal-memory-management/ 譯註:這是本系列最後一篇文章 背景 .NET是一個托管平臺,這意味著記憶體訪問 ...
  • 對於C#的開發的網頁程式,一些企業或者工廠可能會運用這些程式去查詢一些資料,考慮到查詢的資料太多,假如一個月的資料就有上萬條數據,在對於查詢資料的SQL語句後時間欄位運用Between.....AND......對查詢時間範圍進行控制,以免撈取數據太多,查詢時間較長。 根據判斷輸入的時間範圍返回的結 ...
  • 1.前端頁面代碼: 前端頁面代碼主要顯示退出系統或者網站的可視化按鈕代碼,代碼如下:(請忽略項目關鍵字:CPU) <ul class="nav navbar-nav navbar-right"> <li class=""> <a href="javascript:;" class="user-pro ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...