前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1、修改集成方式

1、修改集成方式

作者头像
乔达摩@嘿
发布2022-09-26 16:17:54
3990
发布2022-09-26 16:17:54
举报
文章被收录于专栏:嘿dotNet嘿dotNet
Get Azure key-value pairs from App configuration | Serverless360
Get Azure key-value pairs from App configuration | Serverless360

写在前面

本文重点来讲讲配置中心是怎么配置的动态更新的。

概念定义

一般对配置中心来说都有动态更新的概念,我这里给个定义:

配置中心的动态更新是指,当用户在配置中心管理后台更新配置后,集成的客户端能以某种形式到配置的更新;

一般有两种模式

  • 1、客户端轮询;
  • 2、服务端主动推送更新;包括但不限于Grpc(Nacos),Websocket等方式;

客户端轮询模式

本文在前文基础上开始的,有些略过的地方请看前文;

1、修改集成方式

代码语言:javascript
复制
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("AppConfig");

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    //配置不同功能
    config.AddAzureAppConfiguration(options =>
    {
        ////启用Label(多环境)支持
        //options.Connect(connectionString)
        //    .Select(KeyFilter.Any, LabelFilter.Null)//配置过滤器,读取空Lable的配置
        //    .Select(KeyFilter.Any, hostingContext.HostingEnvironment.EnvironmentName); //配置过滤器,只读取某个环境的配置

        //启用Poll模式的主动更新
        options.Connect(connectionString)
            .Select(KeyFilter.Any, LabelFilter.Null)//配置过滤器,读取空Lable的配置
            .Select(KeyFilter.Any, hostingContext.HostingEnvironment.EnvironmentName) //配置过滤器,只读取某个环境的配置
            .ConfigureRefresh(refresh =>
            {
                refresh.Register("TestApp:Settings:Sentinel", refreshAll: true).SetCacheExpiration(new TimeSpan(0, 0, 30));
            });
    });
});

这里方法ConfigureRefresh参数:

TestApp:Settings:Sentinel:这就是程序轮询的配置Key;

refreshAll=true: 表示当轮询的配置Key更新时,更新所有配置;

SetCacheExpiration:设置多久时间轮询一次,这里设置了30秒,这也是默认值;

2、注入服务

代码语言:javascript
复制
builder.Services.AddAzureAppConfiguration();

3、验证

我们现在配置管理后台设置好key:TestApp:Settings:Sentinel

1659710138480
1659710138480

可以看到初始值==1;

我们新增一个测试的TestKey4==TestKey4-azure

1659710272267
1659710272267

启动程序后,我们无论怎么修改配置后台,都不会程序拿到值始终:TestKey4 ==TestKey4-azure

我们把监控Key:TestApp:Settings:Sentinel设置为2

再次获取可以看到,TestKey4 的值更新了:

1659710583034
1659710583034

OK,轮询模式就是这么朴实无华,却又足以满足大部分需求;

服务端主动推送更新

流程简介

除了轮询的方式动态更新配置外,配置中心也提供了push的方式主动推送配置更新到客户端,不过它的实现流程不太像我们经常遇到的Grpc或者Websocket等那样直连的方式,而是借助Azure消息队列Service Bus实现的。

大体流程:

  1. 先创建一个Service Bus的Topic订阅(类似于RabbitMQ的Topic);
  2. 配置中心注册一个事件订阅到Service Bus的Topic订阅,当配置修改时触发事件发送一个配置更新消息到Service Bus;
  3. 客户端程序订阅了Service Bus的Topic,实时接收配置更新消息并更新本地程序的IConfiguration;

下面我们看看流程怎么实现;

1、先创建Service Bus的Topic订阅

创建Service Bus命名空间

1659796317423
1659796317423

信息自己填

1659796361277
1659796361277

创建Topic

我创建的topic名:config-topic

1659759474037
1659759474037

创建topic订阅

订阅名:config-s1

1659759526382
1659759526382
1659759571039
1659759571039

ok,到这步位置,Service Bus这边基本配置完;

2、创建配置中心的事件订阅到topic订阅

App Configuration下创建事件订阅

填写Topic订阅信息

注意右侧红框,要选择你上步创建的Service Bus 的Topic订阅 config-topic

1659760042342
1659760042342

创建成功

1659760088732
1659760088732

3、Asp.Net Core中集成

安装包

代码语言:javascript
复制
install-package Microsoft.Azure.ServiceBus

新增配置信息

代码语言:javascript
复制
 //ServiceBus 的配置
 "AzureServiceBusConfig": {
    "ConnectionString": "< ConnectionString >",
    "TopicName": "< Your TopicName >", //我的是config-topic
    "SubscriptionName": "< Your SubscriptionName >" // 我的是 config-s1
  }

修改ConfigureService做集成

代码语言:javascript
复制
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("AppConfig");
IConfigurationRefresher _refresher = null;

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    ////简单使用只配置connection string
    //config.AddAzureAppConfiguration(connectionString);

    //配置不同功能
    config.AddAzureAppConfiguration(options =>
    {
        //启用Push模式的主动推送更新配置
        options.Connect(connectionString)
            .Select(KeyFilter.Any, LabelFilter.Null)//配置过滤器,读取空Lable的配置
            .Select(KeyFilter.Any, hostingContext.HostingEnvironment.EnvironmentName) //配置过滤器,只读取某个环境的配置
            .ConfigureRefresh(refresh =>
            {
                refresh.Register("TestApp:Settings:Sentinel", refreshAll: true)
                       .SetCacheExpiration(TimeSpan.FromDays(10)); //这个刷新频率要设置特别低了
            });
        _refresher = options.GetRefresher();

    });
});

TestApp:Settings:Sentinel:只订阅这个key的刷新事件;

SetCacheExpiration:这里的刷新频率设置很低就行;

修改IApplicationBuilder集成

先写个拓展方法

代码语言:javascript
复制
/// <summary>
/// 启用一个Service bus事件处理程序在配置更新时刷新 IConfiguration
/// </summary>
/// <param name="app">The application.</param>
/// <param name="refresher">The refresher.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">serviceBusConfig</exception>
public static IApplicationBuilder UseAzureConfigChangeEventHandler(this IApplicationBuilder app, IConfigurationRefresher refresher)
{
    var serviceBusConfig = PassportConfig.Get<AzureServiceBusConfig>(nameof(AzureServiceBusConfig));
    if (serviceBusConfig == null)
    {
        throw new ArgumentNullException(nameof(serviceBusConfig));
    }

    SubscriptionClient serviceBusClient = new SubscriptionClient(serviceBusConfig.ConnectionString, serviceBusConfig.TopicName, serviceBusConfig.SubscriptionName);

    serviceBusClient.RegisterMessageHandler(handler: (message, cancellationToken) =>
        {
            // 构建一个 EventGridEvent
            EventGridEvent eventGridEvent = EventGridEvent.Parse(BinaryData.FromBytes(message.Body));

            // 创建PushNotification
            eventGridEvent.TryCreatePushNotification(out PushNotification pushNotification);

            // 刷新IConfiguration
            refresher.ProcessPushNotification(pushNotification);
            refresher.TryRefreshAsync();

            return Task.CompletedTask;
        },
        exceptionReceivedHandler: (exceptionargs) =>
        {
            Console.WriteLine($"{exceptionargs.Exception}");
            return Task.CompletedTask;
        }
        );

    return app;
}

然后直接在管道中启用

代码语言:javascript
复制
app.UseAzureConfigChangeEventHandler(_refresher);

这个函数的功能是,订阅Service Bus的Topic ,当服务端配置修改时,接收配置更新信息,刷新本地配置;

验证

还是用TestKey4来测试,先运行程序,

本来:TestKey4TestKey4-azure,我们改成:TestKey4TestKey4-azure 2022年8月6日

1659762724065
1659762724065

但怎么刷新程序获取的值都不会更新。

我们打个断点到函数:UseAzureConfigChangeEventHandler(),再更新Key TestApp:Settings:Sentinel

看到,收到配置更新消息命中断点了:

1659797999344
1659797999344

同时,通过Service Bus的后台,我们也已看到配置更新事件消息正确发送:

1659798843360
1659798843360

我们再次获取配置看到确已更新:

1659762786635
1659762786635

OK,服务端基于订阅消息队列获取配置的主动更新方式验证成功;

总结

1、我觉得动态更新配置用主动轮询的方式基本能满足大部分需求(但是每次轮询消耗次数,请设置好轮询间隔时间),基于消息队列的主动推送方式稍微有点麻烦,看需求选用;

2、当配置中心的Key和本地配置文件的Key冲突时,以配置中心为准;

3、总体来说配置中心还是挺香的,除了贵(毕竟土豪云),价格。

配置中心的基本学习到这里告一段落,后面挖掘到更实用的功能/技巧将再次水文补充;

源码

https://github.com/gebiWangshushu/Hei.Azure.Test

[参考]

https://docs.microsoft.com/en-us/azure/azure-app-configuration/overview

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
  • 概念定义
  • 客户端轮询模式
    • 1、修改集成方式
      • 2、注入服务
        • 3、验证
        • 服务端主动推送更新
          • 流程简介
            • 1、先创建Service Bus的Topic订阅
              • 2、创建配置中心的事件订阅到topic订阅
                • 3、Asp.Net Core中集成
                  • 安装包
                  • 新增配置信息
                  • 修改ConfigureService做集成
                  • 修改IApplicationBuilder集成
                  • 验证
              • 总结
              • 源码
              • [参考]
              相关产品与服务
              消息队列 CMQ 版
              消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档