AI 技能AI 插件人工智能【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址:https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills点击查看免费下载导读本指南以 AAS 仓库中 azure-appconfiguration-ts 技能 为核心骨架,系统讲解在 TypeScript/Node.js 项目中接入 Azure App Configuration 的完整路径:从安装、认证、CRUD 管理,到基于@azure/app-configuration-provider的高层加载、动态刷新、Key Vault 引用,再到@microsoft/feature-management的 Feature Flags 评估与不可变快照(Snapshot)。读完本文,你将能够独立完成"集中式配置中心 + 灰度开关 + 秒级配置热更新"的工程落地,并理解每个 API 背后的设计动机与最佳实践。该技能在 AAS 仓库中登记为cloud类别、risk: critical级别的社区技能,其目录元数据(catalog.json)标记了azure、appconfiguration、ts、feature、flags、dynamic、refresh等触发词,技能来源可追溯到 microsoft-skills-attribution.json 中的typescript/integration/appconfiguration,即面向 TS 集成场景的官方技能衍生。同一系列还包含 Python 版 与 Java 版,便于多语言团队对照使用。为什么需要集中式配置:定位与适用场景Azure App Configuration 是一种集中式配置管理服务,专为"配置与代码分离"而生。与传统的dotenv、本地 JSON 配置相比,它带来的核心能力包括:集中管理:所有环境的配置(开发、测试、生产)集中在同一个服务中,配合label(标签)实现环境隔离,避免配置散落在各分支与部署包里。Feature Flags(功能开关):将新功能的发布开关从代码中剥离,支持按用户、按百分比、按分组进行灰度放量,实现"代码已上线、功能未暴露"的安全发布。动态刷新(Dynamic Refresh):配置变更后应用无需重启即可拉取最新值,配合哨兵(Sentinel)机制可实现全量配置的热更新。快照(Snapshot):为一次发布建立不可变的配置快照,保证"同一发布版本读取同一份配置",杜绝部署与配置错配。从仓库元数据看,该技能被归类为cloud大类下的集成(integration)技能,其典型应用场景是:Agent 或开发者需要在一段代码中完成配置中心的初始化、读取与动态更新,或者需要为应用接入云原生的配置管理基础设施。安装与依赖分层该技能采用"双 SDK + 功能开关库"的分层设计,安装命令如下:# Low-level CRUD SDK npm install @azure/app-configuration @azure/identity # High-level provider (recommended for apps) npm install @azure/app-configuration-provider @azure/identity # Feature flag management npm install @microsoft/feature-management三个包的分工非常清晰,这也是全篇反复出现的关键设计原则:包层级职责使用场景@azure/app-configuration底层 CRUD SDK增删改查配置项、加锁/解锁、管理快照、列举标签管理工具、脚本、运维面板、CI 流水线@azure/app-configuration-provider高层 Provider批量加载配置、映射为键值对象、动态刷新、解析 Key Vault 引用、加载快照运行时应用(Web 服务、函数、CLI 工具)@microsoft/feature-management特性管理库定义 FeatureManager、评估开关、处理 Targeting 过滤器与 Provider 配合做灰度判断实践建议:管理类任务用底层 SDK,运行类任务用 Provider。混用两者时注意上下文区分——底层 SDK 的写入是"配置中心的修改",Provider 的读取是"应用运行态的视图"。环境变量与认证方式环境变量技能约定的两类环境变量(二选一):AZURE_APPCONFIG_ENDPOINT=https://<your-resource>.azconfig.io # OR AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://...;Id=...;Secret=...AZURE_APPCONFIG_ENDPOINT:仅含服务端点,配合 Entra ID(Azure AD)身份认证使用,是推荐的生产方式,不落盘任何密钥。AZURE_APPCONFIG_CONNECTION_STRING:包含Endpoint、Id、Secret的完整连接串,适合本地开发或无法使用托管身份的环境;需注意连接串含明文凭据,应通过密钥管理或环境注入方式传递。认证代码import { AppConfigurationClient } from "@azure/app-configuration"; import { DefaultAzureCredential } from "@azure/identity"; // DefaultAzureCredential (recommended) const client = new AppConfigurationClient( process.env.AZURE_APPCONFIG_ENDPOINT!, new DefaultAzureCredential() ); // Connection string const client2 = new AppConfigurationClient( process.env.AZURE_APPCONFIG_CONNECTION_STRING! );DefaultAzureCredential是@azure/identity提供的链式凭据:它会依次尝试环境变量凭据、托管身份(Managed Identity)、Azure CLI 登录态等,因此同一套代码在本地开发(Azure CLI 登录)与云端部署(托管身份)之间无需改动。这是该技能在认证环节反复强调"推荐 DefaultAzureCredential"的原因——它把"环境适配"从代码中彻底剥离。从 RBAC 角度,只读场景应授予App Configuration Data Reader角色,管理场景则使用App Configuration Data Owner,这一点会在后文"最佳实践"中再次展开。底层 CRUD 操作创建 / 更新配置项// Add new (fails if exists) await client.addConfigurationSetting({ key: "app:settings:message", value: "Hello World", label: "production", contentType: "text/plain", tags: { environment: "prod" }, }); // Set (create or update) await client.setConfigurationSetting({ key: "app:settings:message", value: "Updated value", label: "production", }); // Update with optimistic concurrency const existing = await client.getConfigurationSetting({ key: "myKey" }); existing.value = "new value"; await client.setConfigurationSetting(existing, { onlyIfUnchanged: true });三个方法的语义差异值得注意:addConfigurationSetting:幂等性最弱,键已存在时直接失败,适合"只允许首次写入"的初始化场景(如默认配置、首次种子数据)。setConfigurationSetting:创建或覆盖,无论键是否存在都会成功,是日常写入的主入口。乐观并发(onlyIfUnchanged: true):基于 ETag 校验。只有当服务器端版本与你读取到的版本一致时才允许写入,否则抛出冲突错误。这防止了"读-改-写"之间的并发覆盖,是配置治理中最容易忽略却最关键的一环——多个 Agent 或运维人员同时改同一配置时,乐观并发是防止静默覆盖的底线。读取配置项// Get single setting const setting = await client.getConfigurationSetting({ key: "app:settings:message", label: "production", // optional }); console.log(setting.value); // List with filters const settings = client.listConfigurationSettings({ keyFilter: "app:*", labelFilter: "production", }); for await (const setting of settings) { console.log(`${setting.key}: ${setting.value}`); }listConfigurationSettings返回的是异步迭代器(AsyncIterable),配合for await...of可以流式消费大量配置,无需担心一次性加载内存。过滤器支持通配符模式:keyFilter支持*与?通配(如app:*匹配app:前缀下的所有键),labelFilter同理。省略label即表示"取无标签(null label)的配置",这一点在标签章节会详细展开。删除配置项await client.deleteConfigurationSetting({ key: "app:settings:message", label: "production", });加锁 / 解锁(只读保护)// Lock await client.setReadOnly({ key: "myKey", label: "prod" }, true); // Unlock await client.setReadOnly({ key: "myKey", label: "prod" }, false);锁定(read-only)状态是 App Configuration 的写保护机制:被锁定的配置项将拒绝所有写入与删除操作,直到显式解锁。典型用法是对生产环境的敏感配置或已发布版本对应的配置项加锁,防止误改。高层 Provider:加载与使用配置加载配置(Load)import { load } from "@azure/app-configuration-provider"; import { DefaultAzureCredential } from "@azure/identity"; const appConfig = await load( process.env.AZURE_APPCONFIG_ENDPOINT!, new DefaultAzureCredential(), { selectors: [ { keyFilter: "app:*", labelFilter: "production" }, ], trimKeyPrefixes: ["app:"], } ); // Map-style access const value = appConfig.get("settings:message"); // Object-style access const config = appConfig.constructConfigurationObject({ separator: ":" }); console.log(config.settings.message);load是运行时的核心入口,三个关键配置项:selectors:选择器数组,用keyFilter/labelFilter(或后文的snapshotName)圈定本次加载的配置范围。可传多个选择器实现多范围合并。trimKeyPrefixes:键前缀裁剪。加载后自动剥掉app:前缀,使业务代码直接以settings:message访问,而不是带着前缀的全限定键名。访问方式两种:appConfig.get(key):Map 风格,返回字符串值;constructConfigurationObject({ separator: ":" }):按分隔符(默认:)把扁平的键空间解析为嵌套对象,settings:message即变成config.settings.message,更贴近常规配置对象的访问习惯。动态刷新(Dynamic Refresh)const appConfig = await load(endpoint, credential, { selectors: [{ keyFilter: "app:*" }], refreshOptions: { enabled: true, refreshIntervalInMs: 30_000, // 30 seconds }, }); // Trigger refresh (non-blocking) appConfig.refresh(); // Listen for refresh events const disposer = appConfig.onRefresh(() => { console.log("Configuration refreshed!"); }); // Express middleware pattern app.use((req, res, next) => { appConfig.refresh(); next(); });动态刷新的机制要点:refreshIntervalInMs:节流间隔。注意这不是"每 30 秒必然拉取",而是"两次刷新之间至少间隔 30 秒"。真正触发拉取仍需要显式调用appConfig.refresh(),这是为了控制对配置中心的请求频率。refresh()是非阻塞的:立即返回,后台比对配置版本,有变化才更新内存快照并触发事件。onRefresh(callback)返回一个disposer函数,调用它即可解除监听,避免长生命周期应用中的事件泄漏。Express 中间件模式是 Web 服务中最常见的接入方式:每个请求先触发一次刷新检查(节流内则跳过),再继续业务处理,从而在不阻塞请求的前提下让配置尽量新鲜。Sentinel(哨兵)模式:当配置项众多时,逐键比对开销较大。社区与官方推荐的做法是设置一个专门的哨兵键(如app:sentinel:version),只对哨兵键做刷新检查——哨兵键变化即认为整体配置有更新,触发全量重新加载。该模式会在"最佳实践"中再次强调,它是动态刷新性能与新鲜度之间的平衡点。Key Vault 引用(Secret 自动解析)const appConfig = await load(endpoint, credential, { selectors: [{ keyFilter: "app:*" }], keyVaultOptions: { credential: new DefaultAzureCredential(), secretRefreshIntervalInMs: 7200_000, // 2 hours }, }); // Secrets are automatically resolved const dbPassword = appConfig.get("database:password");App Configuration 支持把某个配置项的值设置为Key Vault 引用(SecretReference),而不是明文密钥。加载时 Provider 会:识别值为 Key Vault 引用的配置项;使用keyVaultOptions.credential(再次是DefaultAzureCredential)向 Azure Key Vault 拉取真实机密;把解析后的值暴露给业务代码——appConfig.get("database:password")拿到的已经是解密后的密码。secretRefreshIntervalInMs(示例 2 小时)控制机密的重新拉取周期,与配置本身的动态刷新相互独立。这套机制把"配置中心"与"密钥保管库"做了清晰的分层:配置中心管非敏感配置 + 指向机密的引用,Key Vault 管真正的敏感数据,业务代码对二者无感知。Feature Flags:从写入到灰度评估创建 Feature Flag(底层 SDK)import { featureFlagPrefix, featureFlagContentType, FeatureFlagValue, ConfigurationSetting, } from "@azure/app-configuration"; const flag: ConfigurationSetting<FeatureFlagValue> = { key: `${featureFlagPrefix}Beta`, contentType: featureFlagContentType, value: { id: "Beta", enabled: true, description: "Beta feature", conditions: { clientFilters: [ { name: "Microsoft.Targeting", parameters: { Audience: { Users: ["user@example.com"], Groups: [{ Name: "beta-testers", RolloutPercentage: 50 }], DefaultRolloutPercentage: 0, }, }, }, ], }, }, }; await client.addConfigurationSetting(flag);Feature Flag 在底层其实是一种特殊格式的配置项:键名带featureFlagPrefix(值为.appconfig.featureflag/),以此与普通配置键区分;内容类型为featureFlagContentType(application/vnd.microsoft.appconfig.ff+json;charset=utf-8);值结构为FeatureFlagValue:id(开关 ID)、enabled(总开关)、conditions.clientFilters(客户端过滤器列表)。示例中的Microsoft.Targeting过滤器是灰度能力的核心:Audience允许按Users(精确用户)、Groups(分组 +RolloutPercentage组内放量百分比)、DefaultRolloutPercentage(默认放量百分比)三个维度做阶梯式灰度。上述配置的含义是:user@example.com必定开启,beta-testers组内 50% 的用户开启,其余用户默认关闭。加载与评估 Feature Flags(Provider + FeatureManager)import { load } from "@azure/app-configuration-provider"; import { ConfigurationMapFeatureFlagProvider, FeatureManager, } from "@microsoft/feature-management"; const appConfig = await load(endpoint, credential, { featureFlagOptions: { enabled: true, selectors: [{ keyFilter: "*" }], refresh: { enabled: true, refreshIntervalInMs: 30_000, }, }, }); const featureProvider = new ConfigurationMapFeatureFlagProvider(appConfig); const featureManager = new FeatureManager(featureProvider); // Simple check const isEnabled = await featureManager.isEnabled("Beta"); // With targeting context const isEnabledForUser = await featureManager.isEnabled("Beta", { userId: "user@example.com", groups: ["beta-testers"], });评估链路的两个关键点:featureFlagOptions启用开关加载:Provider 加载配置时必须显式开启featureFlagOptions.enabled,并为其指定选择器与独立的刷新配置。开关与普通配置使用同一套动态刷新机制,因此灰度开关同样支持秒级热更新——调整放量百分比后,最多一个刷新间隔即可生效。FeatureManager负责评估:它读取clientFilters中的过滤器(如Microsoft.Targeting、Microsoft.TimeWindow等),结合调用方传入的userId/groups上下文算出最终开关值。isEnabled("Beta", context)传入的上下文会被用于 Targeting 过滤器的匹配计算。这套组合实现了真正的"代码与策略分离":业务代码只写if (await featureManager.isEnabled("Beta", ctx)),灰度规则(谁、多少百分比、什么时间段)全部由配置中心动态下发,无需重新部署。快照(Snapshot):不可变的发布配置// Create snapshot const snapshot = await client.beginCreateSnapshotAndWait({ name: "release-v1.0", retentionPeriod: 2592000, // 30 days filters: [{ keyFilter: "app:*", labelFilter: "production" }], }); // Get snapshot const snap = await client.getSnapshot("release-v1.0"); // List settings in snapshot const settings = client.listConfigurationSettingsForSnapshot("release-v1.0"); for await (const setting of settings) { console.log(`${setting.key}: ${setting.value}`); } // Archive/recover await client.archiveSnapshot("release-v1.0"); await client.recoverSnapshot("release-v1.0"); // Load from snapshot (provider) const config = await load(endpoint, credential, { selectors: [{ snapshotName: "release-v1.0" }], });快照是"配置的时间胶囊",核心特性:beginCreateSnapshotAndWait:创建是异步操作(返回 LRO——长时运行操作),...AndWait变体等待其完成。快照会固化创建时刻匹配filters的所有配置项,此后对原键的修改不会影响已生成的快照。retentionPeriod:保留期,单位秒(示例 30 天)。到期自动清理,需在创建时指定。archiveSnapshot/recoverSnapshot:归档与恢复。归档后的快照不可读取/加载,恢复后重新可用——适合"退役发布版本"与"回滚到某版本"的运维场景。Provider 侧加载:selectors中使用snapshotName代替keyFilter/labelFilter,即可让应用直接以某个发布快照为配置源。这与"同一发布版本绑定同一份配置"的发布理念完全吻合:每次发布创建快照,应用按发布版本名加载,杜绝了"部署在 10 分钟后读到的却是别人改过的配置"这类漂移问题。标签(Labels):环境隔离的基石// Create settings with labels await client.setConfigurationSetting({ key: "database:host", value: "dev-db.example.com", label: "development", }); await client.setConfigurationSetting({ key: "database:host", value: "prod-db.example.com", label: "production", }); // Filter by label const prodSettings = client.listConfigurationSettings({ keyFilter: "*", labelFilter: "production", }); // No label (null label) const noLabelSettings = client.listConfigurationSettings({ labelFilter: "\0", }); // List available labels for await (const label of client.listLabels()) { console.log(label.name); }标签机制的要点:同一个key可以有多个 label 版本:database:host在development与production下各存一份值,互不干扰。这是 App Configuration 实现多环境共存的根本机制——一份代码,多套配置。label 过滤器是精确匹配(非通配),labelFilter: "production"只取生产标签。null label 的特殊性:未指定 label 的配置项其 label 是空(null)。查询"无标签配置"需要使用特殊的"\0"过滤器——这是 SDK 中容易踩坑的点:省略labelFilter会返回所有标签的配置(含无标签项),而传"\0"只返回无标签项。listLabels()提供全局标签枚举,可用于配置管理面板的环境下拉框或自动化脚本的标签巡检。键类型总览(Key Types)技能汇总了完整 SDK 导入面,覆盖全部三类配置项:import { AppConfigurationClient, ConfigurationSetting, FeatureFlagValue, SecretReferenceValue, featureFlagPrefix, featureFlagContentType, secretReferenceContentType, ListConfigurationSettingsOptions, } from "@azure/app-configuration"; import { load } from "@azure/app-configuration-provider"; import { FeatureManager, ConfigurationMapFeatureFlagProvider, } from "@microsoft/feature-management";三类配置项的内在结构:类型标识方式值结构典型用途普通配置(Key-Value)任意 key +contentType任意字符串常规参数、URL、开关阈值Feature FlagfeatureFlagPrefix前缀 +featureFlagContentTypeFeatureFlagValue功能灰度、渐进发布Secret ReferencesecretReferenceContentTypeSecretReferenceValue(指向 Key Vault 机密)数据库密码、API Key 等敏感数据ConfigurationSetting<T>是泛型容器,T可为string、FeatureFlagValue或SecretReferenceValue;ListConfigurationSettingsOptions提供分页与过滤的完整选项类型。理解这三类键的"按内容类型分派"机制,就能明白为什么 Provider 能在一个加载流程里同时处理普通配置、开关和机密引用。最佳实践清单技能在末尾给出的七条最佳实践,是整个方案设计的浓缩:应用用 Provider:@azure/app-configuration-provider面向运行时配置加载,自带选择器、刷新、Key Vault 解析能力,避免在业务代码里手动拼装底层读取逻辑。管理用底层 SDK:@azure/app-configuration负责 CRUD、加锁、快照、标签管理,适合管理脚本与运维工具。启用刷新(Enable refresh):动态配置是集中式配置的核心价值之一,务必为生产应用开启refreshOptions并接入请求中间件或周期触发器。用标签隔离环境(Use labels):开发/测试/生产各用独立 label,配合labelFilter精确取数,防止环境串扰。用快照保证不可变(Use snapshots):发布时创建快照、应用按snapshotName加载,实现"发布即冻结"的配置一致性。哨兵模式(Sentinel pattern):以专用哨兵键触发全量刷新,在大配置集场景下显著降低刷新比对开销。RBAC 最小权限:只读服务授予App Configuration Data Reader,管理场景才授予写入/所有者角色;配合连接串与 Endpoint 二选一的原则,避免在生产环境硬编码连接串。使用边界与注意事项(When to Use / Limitations)该技能明确适用于"上述工作流或动作"——即 TypeScript 项目中配置中心接入、开关评估与动态刷新相关的开发任务。同时技能也划定了使用边界,值得在工程中作为纪律遵守:仅在任务与上述范围明确匹配时使用:不要把该技能泛化用于其他 Azure 服务(如 Key Vault 直连、Cosmos DB)或非 TypeScript 场景,那应转向 Python 版、Java 版 或其他专项技能。输出不能替代环境专属验证:配置项、RBAC 权限、网络策略(如私有终结点、防火墙)都随具体环境而异,代码层面的正确性不代表生产环境可用,落地前必须做环境级验证与测试。缺少关键前提时主动确认:当必需的输入(如端点/连接串、凭据权限、安全边界)或成功标准缺失时,应先澄清再行动,而不是带着不完整的上下文继续执行。结语从底层 CRUD 到高层 Provider,从普通配置到 Feature Flags 与 Key Vault 引用,再到快照、标签与哨兵刷新,Azure App Configuration 为 TypeScript 应用提供了一套完整的集中配置治理方案。本技能给出的是可直接落地的代码骨架与选择决策——管理用底层 SDK、运行用 Provider、灰度用 FeatureManager、发布用快照、环境隔离用标签。以此为基准,你可以在此基础上按团队的 RBAC 策略、刷新频率与发布流程做进一步定制,把"配置漂移"和"重启生效"这两个分布式系统经典痛点挡在架构之外。赞分享AI 技能AI 插件人工智能【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址:https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills点击查看免费下载相关推荐Aspire 集成 Azure App Configuration:配置、预置与本地模拟器实战指南Aspire 集成 Azure App Configuration:配置、预置与本地模拟器实战指南 本指南以 Aspire 开源仓库中的 Aspire.Host云原生微服务后端可观测性Azure App Configuration Python SDK 实战指南:配置中心、功能开关与动态设置Azure App Configuration Python SDK 实战指南:配置中心、功能开关与动态设置 本指南基于开源仓库 agentic awesomeAI 技能AI 插件人工智能Azure App Configuration JavaScript Client 实战指南:基于 `@azure/app-configuration` 1.11.0 的配置存储读写Azure App Configuration JavaScript Client 实战指南:基于 @azure/app configuration 1.11.上一篇:G-Helper架构重构与华硕笔记本性能优化策略下一篇:深度解析ProperTree:跨平台Plist编辑器的技术革命创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
AI 技能AI 插件人工智能【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址:https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills点击查看免费下载导读本指南以 AAS 仓库中 azure-appconfiguration-ts 技能 为核心骨架,系统讲解在 TypeScript/Node.js 项目中接入 Azure App Configuration 的完整路径:从安装、认证、CRUD 管理,到基于@azure/app-configuration-provider的高层加载、动态刷新、Key Vault 引用,再到@microsoft/feature-management的 Feature Flags 评估与不可变快照(Snapshot)。读完本文,你将能够独立完成"集中式配置中心 + 灰度开关 + 秒级配置热更新"的工程落地,并理解每个 API 背后的设计动机与最佳实践。该技能在 AAS 仓库中登记为cloud类别、risk: critical级别的社区技能,其目录元数据(catalog.json)标记了azure、appconfiguration、ts、feature、flags、dynamic、refresh等触发词,技能来源可追溯到 microsoft-skills-attribution.json 中的typescript/integration/appconfiguration,即面向 TS 集成场景的官方技能衍生。同一系列还包含 Python 版 与 Java 版,便于多语言团队对照使用。为什么需要集中式配置:定位与适用场景Azure App Configuration 是一种集中式配置管理服务,专为"配置与代码分离"而生。与传统的dotenv、本地 JSON 配置相比,它带来的核心能力包括:集中管理:所有环境的配置(开发、测试、生产)集中在同一个服务中,配合label(标签)实现环境隔离,避免配置散落在各分支与部署包里。Feature Flags(功能开关):将新功能的发布开关从代码中剥离,支持按用户、按百分比、按分组进行灰度放量,实现"代码已上线、功能未暴露"的安全发布。动态刷新(Dynamic Refresh):配置变更后应用无需重启即可拉取最新值,配合哨兵(Sentinel)机制可实现全量配置的热更新。快照(Snapshot):为一次发布建立不可变的配置快照,保证"同一发布版本读取同一份配置",杜绝部署与配置错配。从仓库元数据看,该技能被归类为cloud大类下的集成(integration)技能,其典型应用场景是:Agent 或开发者需要在一段代码中完成配置中心的初始化、读取与动态更新,或者需要为应用接入云原生的配置管理基础设施。安装与依赖分层该技能采用"双 SDK + 功能开关库"的分层设计,安装命令如下:# Low-level CRUD SDK npm install @azure/app-configuration @azure/identity # High-level provider (recommended for apps) npm install @azure/app-configuration-provider @azure/identity # Feature flag management npm install @microsoft/feature-management三个包的分工非常清晰,这也是全篇反复出现的关键设计原则:包层级职责使用场景@azure/app-configuration底层 CRUD SDK增删改查配置项、加锁/解锁、管理快照、列举标签管理工具、脚本、运维面板、CI 流水线@azure/app-configuration-provider高层 Provider批量加载配置、映射为键值对象、动态刷新、解析 Key Vault 引用、加载快照运行时应用(Web 服务、函数、CLI 工具)@microsoft/feature-management特性管理库定义 FeatureManager、评估开关、处理 Targeting 过滤器与 Provider 配合做灰度判断实践建议:管理类任务用底层 SDK,运行类任务用 Provider。混用两者时注意上下文区分——底层 SDK 的写入是"配置中心的修改",Provider 的读取是"应用运行态的视图"。环境变量与认证方式环境变量技能约定的两类环境变量(二选一):AZURE_APPCONFIG_ENDPOINT=https://<your-resource>.azconfig.io # OR AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://...;Id=...;Secret=...AZURE_APPCONFIG_ENDPOINT:仅含服务端点,配合 Entra ID(Azure AD)身份认证使用,是推荐的生产方式,不落盘任何密钥。AZURE_APPCONFIG_CONNECTION_STRING:包含Endpoint、Id、Secret的完整连接串,适合本地开发或无法使用托管身份的环境;需注意连接串含明文凭据,应通过密钥管理或环境注入方式传递。认证代码import { AppConfigurationClient } from "@azure/app-configuration"; import { DefaultAzureCredential } from "@azure/identity"; // DefaultAzureCredential (recommended) const client = new AppConfigurationClient( process.env.AZURE_APPCONFIG_ENDPOINT!, new DefaultAzureCredential() ); // Connection string const client2 = new AppConfigurationClient( process.env.AZURE_APPCONFIG_CONNECTION_STRING! );DefaultAzureCredential是@azure/identity提供的链式凭据:它会依次尝试环境变量凭据、托管身份(Managed Identity)、Azure CLI 登录态等,因此同一套代码在本地开发(Azure CLI 登录)与云端部署(托管身份)之间无需改动。这是该技能在认证环节反复强调"推荐 DefaultAzureCredential"的原因——它把"环境适配"从代码中彻底剥离。从 RBAC 角度,只读场景应授予App Configuration Data Reader角色,管理场景则使用App Configuration Data Owner,这一点会在后文"最佳实践"中再次展开。底层 CRUD 操作创建 / 更新配置项// Add new (fails if exists) await client.addConfigurationSetting({ key: "app:settings:message", value: "Hello World", label: "production", contentType: "text/plain", tags: { environment: "prod" }, }); // Set (create or update) await client.setConfigurationSetting({ key: "app:settings:message", value: "Updated value", label: "production", }); // Update with optimistic concurrency const existing = await client.getConfigurationSetting({ key: "myKey" }); existing.value = "new value"; await client.setConfigurationSetting(existing, { onlyIfUnchanged: true });三个方法的语义差异值得注意:addConfigurationSetting:幂等性最弱,键已存在时直接失败,适合"只允许首次写入"的初始化场景(如默认配置、首次种子数据)。setConfigurationSetting:创建或覆盖,无论键是否存在都会成功,是日常写入的主入口。乐观并发(onlyIfUnchanged: true):基于 ETag 校验。只有当服务器端版本与你读取到的版本一致时才允许写入,否则抛出冲突错误。这防止了"读-改-写"之间的并发覆盖,是配置治理中最容易忽略却最关键的一环——多个 Agent 或运维人员同时改同一配置时,乐观并发是防止静默覆盖的底线。读取配置项// Get single setting const setting = await client.getConfigurationSetting({ key: "app:settings:message", label: "production", // optional }); console.log(setting.value); // List with filters const settings = client.listConfigurationSettings({ keyFilter: "app:*", labelFilter: "production", }); for await (const setting of settings) { console.log(`${setting.key}: ${setting.value}`); }listConfigurationSettings返回的是异步迭代器(AsyncIterable),配合for await...of可以流式消费大量配置,无需担心一次性加载内存。过滤器支持通配符模式:keyFilter支持*与?通配(如app:*匹配app:前缀下的所有键),labelFilter同理。省略label即表示"取无标签(null label)的配置",这一点在标签章节会详细展开。删除配置项await client.deleteConfigurationSetting({ key: "app:settings:message", label: "production", });加锁 / 解锁(只读保护)// Lock await client.setReadOnly({ key: "myKey", label: "prod" }, true); // Unlock await client.setReadOnly({ key: "myKey", label: "prod" }, false);锁定(read-only)状态是 App Configuration 的写保护机制:被锁定的配置项将拒绝所有写入与删除操作,直到显式解锁。典型用法是对生产环境的敏感配置或已发布版本对应的配置项加锁,防止误改。高层 Provider:加载与使用配置加载配置(Load)import { load } from "@azure/app-configuration-provider"; import { DefaultAzureCredential } from "@azure/identity"; const appConfig = await load( process.env.AZURE_APPCONFIG_ENDPOINT!, new DefaultAzureCredential(), { selectors: [ { keyFilter: "app:*", labelFilter: "production" }, ], trimKeyPrefixes: ["app:"], } ); // Map-style access const value = appConfig.get("settings:message"); // Object-style access const config = appConfig.constructConfigurationObject({ separator: ":" }); console.log(config.settings.message);load是运行时的核心入口,三个关键配置项:selectors:选择器数组,用keyFilter/labelFilter(或后文的snapshotName)圈定本次加载的配置范围。可传多个选择器实现多范围合并。trimKeyPrefixes:键前缀裁剪。加载后自动剥掉app:前缀,使业务代码直接以settings:message访问,而不是带着前缀的全限定键名。访问方式两种:appConfig.get(key):Map 风格,返回字符串值;constructConfigurationObject({ separator: ":" }):按分隔符(默认:)把扁平的键空间解析为嵌套对象,settings:message即变成config.settings.message,更贴近常规配置对象的访问习惯。动态刷新(Dynamic Refresh)const appConfig = await load(endpoint, credential, { selectors: [{ keyFilter: "app:*" }], refreshOptions: { enabled: true, refreshIntervalInMs: 30_000, // 30 seconds }, }); // Trigger refresh (non-blocking) appConfig.refresh(); // Listen for refresh events const disposer = appConfig.onRefresh(() => { console.log("Configuration refreshed!"); }); // Express middleware pattern app.use((req, res, next) => { appConfig.refresh(); next(); });动态刷新的机制要点:refreshIntervalInMs:节流间隔。注意这不是"每 30 秒必然拉取",而是"两次刷新之间至少间隔 30 秒"。真正触发拉取仍需要显式调用appConfig.refresh(),这是为了控制对配置中心的请求频率。refresh()是非阻塞的:立即返回,后台比对配置版本,有变化才更新内存快照并触发事件。onRefresh(callback)返回一个disposer函数,调用它即可解除监听,避免长生命周期应用中的事件泄漏。Express 中间件模式是 Web 服务中最常见的接入方式:每个请求先触发一次刷新检查(节流内则跳过),再继续业务处理,从而在不阻塞请求的前提下让配置尽量新鲜。Sentinel(哨兵)模式:当配置项众多时,逐键比对开销较大。社区与官方推荐的做法是设置一个专门的哨兵键(如app:sentinel:version),只对哨兵键做刷新检查——哨兵键变化即认为整体配置有更新,触发全量重新加载。该模式会在"最佳实践"中再次强调,它是动态刷新性能与新鲜度之间的平衡点。Key Vault 引用(Secret 自动解析)const appConfig = await load(endpoint, credential, { selectors: [{ keyFilter: "app:*" }], keyVaultOptions: { credential: new DefaultAzureCredential(), secretRefreshIntervalInMs: 7200_000, // 2 hours }, }); // Secrets are automatically resolved const dbPassword = appConfig.get("database:password");App Configuration 支持把某个配置项的值设置为Key Vault 引用(SecretReference),而不是明文密钥。加载时 Provider 会:识别值为 Key Vault 引用的配置项;使用keyVaultOptions.credential(再次是DefaultAzureCredential)向 Azure Key Vault 拉取真实机密;把解析后的值暴露给业务代码——appConfig.get("database:password")拿到的已经是解密后的密码。secretRefreshIntervalInMs(示例 2 小时)控制机密的重新拉取周期,与配置本身的动态刷新相互独立。这套机制把"配置中心"与"密钥保管库"做了清晰的分层:配置中心管非敏感配置 + 指向机密的引用,Key Vault 管真正的敏感数据,业务代码对二者无感知。Feature Flags:从写入到灰度评估创建 Feature Flag(底层 SDK)import { featureFlagPrefix, featureFlagContentType, FeatureFlagValue, ConfigurationSetting, } from "@azure/app-configuration"; const flag: ConfigurationSetting<FeatureFlagValue> = { key: `${featureFlagPrefix}Beta`, contentType: featureFlagContentType, value: { id: "Beta", enabled: true, description: "Beta feature", conditions: { clientFilters: [ { name: "Microsoft.Targeting", parameters: { Audience: { Users: ["user@example.com"], Groups: [{ Name: "beta-testers", RolloutPercentage: 50 }], DefaultRolloutPercentage: 0, }, }, }, ], }, }, }; await client.addConfigurationSetting(flag);Feature Flag 在底层其实是一种特殊格式的配置项:键名带featureFlagPrefix(值为.appconfig.featureflag/),以此与普通配置键区分;内容类型为featureFlagContentType(application/vnd.microsoft.appconfig.ff+json;charset=utf-8);值结构为FeatureFlagValue:id(开关 ID)、enabled(总开关)、conditions.clientFilters(客户端过滤器列表)。示例中的Microsoft.Targeting过滤器是灰度能力的核心:Audience允许按Users(精确用户)、Groups(分组 +RolloutPercentage组内放量百分比)、DefaultRolloutPercentage(默认放量百分比)三个维度做阶梯式灰度。上述配置的含义是:user@example.com必定开启,beta-testers组内 50% 的用户开启,其余用户默认关闭。加载与评估 Feature Flags(Provider + FeatureManager)import { load } from "@azure/app-configuration-provider"; import { ConfigurationMapFeatureFlagProvider, FeatureManager, } from "@microsoft/feature-management"; const appConfig = await load(endpoint, credential, { featureFlagOptions: { enabled: true, selectors: [{ keyFilter: "*" }], refresh: { enabled: true, refreshIntervalInMs: 30_000, }, }, }); const featureProvider = new ConfigurationMapFeatureFlagProvider(appConfig); const featureManager = new FeatureManager(featureProvider); // Simple check const isEnabled = await featureManager.isEnabled("Beta"); // With targeting context const isEnabledForUser = await featureManager.isEnabled("Beta", { userId: "user@example.com", groups: ["beta-testers"], });评估链路的两个关键点:featureFlagOptions启用开关加载:Provider 加载配置时必须显式开启featureFlagOptions.enabled,并为其指定选择器与独立的刷新配置。开关与普通配置使用同一套动态刷新机制,因此灰度开关同样支持秒级热更新——调整放量百分比后,最多一个刷新间隔即可生效。FeatureManager负责评估:它读取clientFilters中的过滤器(如Microsoft.Targeting、Microsoft.TimeWindow等),结合调用方传入的userId/groups上下文算出最终开关值。isEnabled("Beta", context)传入的上下文会被用于 Targeting 过滤器的匹配计算。这套组合实现了真正的"代码与策略分离":业务代码只写if (await featureManager.isEnabled("Beta", ctx)),灰度规则(谁、多少百分比、什么时间段)全部由配置中心动态下发,无需重新部署。快照(Snapshot):不可变的发布配置// Create snapshot const snapshot = await client.beginCreateSnapshotAndWait({ name: "release-v1.0", retentionPeriod: 2592000, // 30 days filters: [{ keyFilter: "app:*", labelFilter: "production" }], }); // Get snapshot const snap = await client.getSnapshot("release-v1.0"); // List settings in snapshot const settings = client.listConfigurationSettingsForSnapshot("release-v1.0"); for await (const setting of settings) { console.log(`${setting.key}: ${setting.value}`); } // Archive/recover await client.archiveSnapshot("release-v1.0"); await client.recoverSnapshot("release-v1.0"); // Load from snapshot (provider) const config = await load(endpoint, credential, { selectors: [{ snapshotName: "release-v1.0" }], });快照是"配置的时间胶囊",核心特性:beginCreateSnapshotAndWait:创建是异步操作(返回 LRO——长时运行操作),...AndWait变体等待其完成。快照会固化创建时刻匹配filters的所有配置项,此后对原键的修改不会影响已生成的快照。retentionPeriod:保留期,单位秒(示例 30 天)。到期自动清理,需在创建时指定。archiveSnapshot/recoverSnapshot:归档与恢复。归档后的快照不可读取/加载,恢复后重新可用——适合"退役发布版本"与"回滚到某版本"的运维场景。Provider 侧加载:selectors中使用snapshotName代替keyFilter/labelFilter,即可让应用直接以某个发布快照为配置源。这与"同一发布版本绑定同一份配置"的发布理念完全吻合:每次发布创建快照,应用按发布版本名加载,杜绝了"部署在 10 分钟后读到的却是别人改过的配置"这类漂移问题。标签(Labels):环境隔离的基石// Create settings with labels await client.setConfigurationSetting({ key: "database:host", value: "dev-db.example.com", label: "development", }); await client.setConfigurationSetting({ key: "database:host", value: "prod-db.example.com", label: "production", }); // Filter by label const prodSettings = client.listConfigurationSettings({ keyFilter: "*", labelFilter: "production", }); // No label (null label) const noLabelSettings = client.listConfigurationSettings({ labelFilter: "\0", }); // List available labels for await (const label of client.listLabels()) { console.log(label.name); }标签机制的要点:同一个key可以有多个 label 版本:database:host在development与production下各存一份值,互不干扰。这是 App Configuration 实现多环境共存的根本机制——一份代码,多套配置。label 过滤器是精确匹配(非通配),labelFilter: "production"只取生产标签。null label 的特殊性:未指定 label 的配置项其 label 是空(null)。查询"无标签配置"需要使用特殊的"\0"过滤器——这是 SDK 中容易踩坑的点:省略labelFilter会返回所有标签的配置(含无标签项),而传"\0"只返回无标签项。listLabels()提供全局标签枚举,可用于配置管理面板的环境下拉框或自动化脚本的标签巡检。键类型总览(Key Types)技能汇总了完整 SDK 导入面,覆盖全部三类配置项:import { AppConfigurationClient, ConfigurationSetting, FeatureFlagValue, SecretReferenceValue, featureFlagPrefix, featureFlagContentType, secretReferenceContentType, ListConfigurationSettingsOptions, } from "@azure/app-configuration"; import { load } from "@azure/app-configuration-provider"; import { FeatureManager, ConfigurationMapFeatureFlagProvider, } from "@microsoft/feature-management";三类配置项的内在结构:类型标识方式值结构典型用途普通配置(Key-Value)任意 key +contentType任意字符串常规参数、URL、开关阈值Feature FlagfeatureFlagPrefix前缀 +featureFlagContentTypeFeatureFlagValue功能灰度、渐进发布Secret ReferencesecretReferenceContentTypeSecretReferenceValue(指向 Key Vault 机密)数据库密码、API Key 等敏感数据ConfigurationSetting<T>是泛型容器,T可为string、FeatureFlagValue或SecretReferenceValue;ListConfigurationSettingsOptions提供分页与过滤的完整选项类型。理解这三类键的"按内容类型分派"机制,就能明白为什么 Provider 能在一个加载流程里同时处理普通配置、开关和机密引用。最佳实践清单技能在末尾给出的七条最佳实践,是整个方案设计的浓缩:应用用 Provider:@azure/app-configuration-provider面向运行时配置加载,自带选择器、刷新、Key Vault 解析能力,避免在业务代码里手动拼装底层读取逻辑。管理用底层 SDK:@azure/app-configuration负责 CRUD、加锁、快照、标签管理,适合管理脚本与运维工具。启用刷新(Enable refresh):动态配置是集中式配置的核心价值之一,务必为生产应用开启refreshOptions并接入请求中间件或周期触发器。用标签隔离环境(Use labels):开发/测试/生产各用独立 label,配合labelFilter精确取数,防止环境串扰。用快照保证不可变(Use snapshots):发布时创建快照、应用按snapshotName加载,实现"发布即冻结"的配置一致性。哨兵模式(Sentinel pattern):以专用哨兵键触发全量刷新,在大配置集场景下显著降低刷新比对开销。RBAC 最小权限:只读服务授予App Configuration Data Reader,管理场景才授予写入/所有者角色;配合连接串与 Endpoint 二选一的原则,避免在生产环境硬编码连接串。使用边界与注意事项(When to Use / Limitations)该技能明确适用于"上述工作流或动作"——即 TypeScript 项目中配置中心接入、开关评估与动态刷新相关的开发任务。同时技能也划定了使用边界,值得在工程中作为纪律遵守:仅在任务与上述范围明确匹配时使用:不要把该技能泛化用于其他 Azure 服务(如 Key Vault 直连、Cosmos DB)或非 TypeScript 场景,那应转向 Python 版、Java 版 或其他专项技能。输出不能替代环境专属验证:配置项、RBAC 权限、网络策略(如私有终结点、防火墙)都随具体环境而异,代码层面的正确性不代表生产环境可用,落地前必须做环境级验证与测试。缺少关键前提时主动确认:当必需的输入(如端点/连接串、凭据权限、安全边界)或成功标准缺失时,应先澄清再行动,而不是带着不完整的上下文继续执行。结语从底层 CRUD 到高层 Provider,从普通配置到 Feature Flags 与 Key Vault 引用,再到快照、标签与哨兵刷新,Azure App Configuration 为 TypeScript 应用提供了一套完整的集中配置治理方案。本技能给出的是可直接落地的代码骨架与选择决策——管理用底层 SDK、运行用 Provider、灰度用 FeatureManager、发布用快照、环境隔离用标签。以此为基准,你可以在此基础上按团队的 RBAC 策略、刷新频率与发布流程做进一步定制,把"配置漂移"和"重启生效"这两个分布式系统经典痛点挡在架构之外。赞分享AI 技能AI 插件人工智能【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址:https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills点击查看免费下载相关推荐Aspire 集成 Azure App Configuration:配置、预置与本地模拟器实战指南Aspire 集成 Azure App Configuration:配置、预置与本地模拟器实战指南 本指南以 Aspire 开源仓库中的 Aspire.Host云原生微服务后端可观测性Azure App Configuration Python SDK 实战指南:配置中心、功能开关与动态设置Azure App Configuration Python SDK 实战指南:配置中心、功能开关与动态设置 本指南基于开源仓库 agentic awesomeAI 技能AI 插件人工智能Azure App Configuration JavaScript Client 实战指南:基于 `@azure/app-configuration` 1.11.0 的配置存储读写Azure App Configuration JavaScript Client 实战指南:基于 @azure/app configuration 1.11.上一篇:G-Helper架构重构与华硕笔记本性能优化策略下一篇:深度解析ProperTree:跨平台Plist编辑器的技术革命创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考