AzureのApp Configurationはアプリケーションの設定値などを一律管理できるサービスです。そんなApp Configurationには機能フラグという機能があります。今回はこの機能フラグを実際に使ってみて、使用感や普通の設定値を格納する方法との違いについてまとめていきます。
結論
- 機能フラグはbool値を持つデータである
- 機能フラグのデータを変更することで、アプリの挙動を変える際に利用できる
- 機能フラグ変更の反映タイミングはキャッシュ期間を設定することで自由に調整できる
- 設定値をTrue/Falseで管理する場合は機能フラグを使用する
環境
サンプルアプリはAzure Functionsのisolatedで実装して、動作確認を行います。
基本情報
言語 | .NET 6(6.0.413) |
関数の言語 | isolated(分離ワーカープロセス) |
App Configuration | Free |
OS | Windows 11 |
使用する機能フラグ
機能フラグ | 値 | 備考 |
Beta | True |
機能フラグ
見たほうが早いと思うので、さっそくAzure Portalから1つ機能フラグを追加してみましょう。英語ではありますが、以下に機能フラグを追加する際の設定画面を示します。
今回はBetaという名前で機能フラグを追加します。一番上のEnable feature flagは設定値でTrueかFalseになります。もちろんチェックを付けるとTrueになります。keyはデフォルトで名前が適用されます。ラベルと同じく、機能フラグをアプリから取得する際のフィルターに使えるようです。ちなみにkeyは名前と同一である必要はないので任意の文字列を指定できます。Feature filtersに関しては次回試そうと思うので、今回は説明は省略します。
実際に作成された機能フラグはPortalからは以下のように見えます。このBetaはbool値(True or False)を持ちます。現在はTrueとなっています。
使用方法としては、最初はFalseとしてアプリをリリースしておき、途中でTrueに変更することでアプリで新しい機能を使えるようにするといったことが考えられます。つまりアプリをデプロイし直さずにアプリの機能をOn/Offできます。切り替えもEnabledをクリックするだけで簡単に行うことができます。
実践
機能フラグについて理解しましたので、ローカルのAzure Functionsから利用してみたいと思います。Azure Functions(isolated)で機能フラグを利用する方法は以下の公式ドキュメントが参考になります。
App Configurationの設定値を使う場合は「Microsoft.Azure.AppConfiguration.Functions.Worker」をインストールしましたが、機能フラグを使用するには新たに「Microsoft.FeatureManagement」が必要になります。
public static void Main()
{
var host = new HostBuilder()
.ConfigureAppConfiguration(builder =>
{
builder.AddAzureAppConfiguration(options =>
{
options.Connect(appcs_con_string)
.UseFeatureFlags(); // 機能フラグを使うことを宣言
});
})
.ConfigureServices(s =>
{
s.AddAzureAppConfiguration();
// DIのための設定
s.AddFeatureManagement();
})
.ConfigureFunctionsWorkerDefaults(app =>
{
app.UseAzureAppConfiguration();
})
.Build();
host.Run();
}
Program.csの16行目でDIしたことにより、コンストラクタ(Test1)でIFeatureManagerSnapshotインスタンスを受け取っています。公式ドキュメントでは「IConfigurationRefresherインスタンス」も受け取っていましたが、こちらはなくても問題なく動作しました。IConfigurationも今回は設定値を使用していないため、なくても大丈夫です。
private readonly ILogger _logger;
private readonly IConfiguration _configuration;
private readonly IFeatureManagerSnapshot _featureManagerSnapshot;
public Test1(ILoggerFactory loggerFactory, IConfiguration configuration, IFeatureManagerSnapshot featureManagerSnapshot)
{
_logger = loggerFactory.CreateLogger<Test1>();
_configuration = configuration;
_featureManagerSnapshot = featureManagerSnapshot;
}
[Function("Test1")]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
{
var time = DateTime.Now.ToString("hh:mm:ss");
// get feature
bool featureEnalbed = await _featureManagerSnapshot.IsEnabledAsync("Beta");
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString($"{time} Beta:{featureEnalbed}");
return response;
}
動作確認
10秒おきに関数を実行してレスポンスを表示させます。レスポンスにはApp Condifurationから取得した機能フラグBetaの値を出力します。実行途中でAzure Portalから機能フラグBetaをFalseに変更してレスポンスがどう変化するか確認します。またApp Configurationのアクセスログから実際のリクエストについても確認します。
11時54分頃にFalseに変更しました。すると、約40秒後にレスポンスの内容も変更されました。先ほどのTest1のコードを見ると、18行目でBetaの値を読み取っています。この時、デフォルトでキャッシュ期間が30秒に設定されています。そのためPortalから値を変更した際は約30秒後に新しい値を読み取ることができます。今回はアクセスのタイミングで10秒ほど遅くなりましたが、おおよそ30秒後に更新された値を取得できたことが分かります。
また、ログを見るとおよそ30秒ごとにアクセスされていることが分かります。キャッシュが機能している証拠です。GETが機能フラグを読み取るリクエストです。1つだけPUTがありますが、これはPortalから機能フラグの値を変更した際のリクエストです。
キャッシュ期間を変更してみよう
キャッシュ期間を変更したい場合は、Program.csのUseFeatureFlags内でCacheExpirationIntervalを指定します。
.ConfigureAppConfiguration(builder =>
{
builder.AddAzureAppConfiguration(options =>
{
options.Connect(appcs_con_string)
.UseFeatureFlags(featureOption =>
{
featureOption.CacheExpirationInterval = TimeSpan.FromMinutes(5);
});
});
})
先ほどと同様にローカルでAzure Functionsを起動してリクエストを投げてみます。そしてログを確認すると、5分毎にアクセスされていることが分かります。キャッシュ期間が指定した通り5分で設定されていることが分かります。
まとめ
今回はApp Condifurationの機能フラグを試しました。機能フラグはbool値を持ちます。TrueかFalseでアプリの動作を途中で変更したい場合には、この機能フラグを利用することでアプリを際デプロイすることなく変更することができます。
App Configurationは機能フラグとは別の機能でKey-Value形式で値を格納できます。こちらも値を変更することで、その変更をアプリで検知してアプリの動作を変えることはできます。しかし、Key-Value形式ではテキストとして保持されます。単純なTrue/Falseだけで管理したい場合は機能フラグを使用したほうがシンプルになります。また、値の更新(Azure Portalから)に関しても、機能フラグのほうが楽です。
ちなみに、機能フラグの値はTest1の8行目(コンストラクタ)のconfigurationにも格納されています。しかしこちらは文字列として取得されるので、素直に機能フラグ用のモジュールを使ったほうがいいと思います。
True/Falseの2者択一の場合は機能フラグ、それ以外はKey-Value値を使うといいのではないでしょうか。
Key-Value値を動的に読み取る設定方法に関しては下記の記事にまとめていますので、ぜひご覧ください。
また、今回省略したフィルターについては下記の記事で試していますので、ぜひご覧ください。
コメント