XiHan Framework 处于预览阶段

查看获取方式
跳转到内容

配置与选项 ​

本章讲应用与框架怎样读配置:.NET 原生配置源与选项、XiHan:<领域> 配置节、挂载的配置目录与热更新、资源绑定、远程配置与密钥。适用于编写特性、准备部署配置的开发者。

完整 API 见 Configuration.Abstractions 与 Configuration.Nacos 包页。

配置模型 ​

框架不另造配置模型。应用与框架都读 Microsoft.Extensions.Configuration 的 IConfiguration,配置源仍是 appsettings.json、appsettings.<环境>.json、环境变量与命令行这些 .NET 原生来源,没有「默认配置包」。Configuration.Abstractions 只定义两个 Provider 契约(远程配置客户端与密钥库)和把它们接进 IConfigurationBuilder 的配置源。

框架包的选项是带 ConfigurationSection 常量的 record(KernelOptions、LocalizationOptions、FileSystemObjectStorageOptions 等),由各自的静态方法 FromConfiguration(IConfiguration) 逐键读取,不经反射绑定,因而在 Native AOT 下照常工作。特性在装配时读取一次并登记为单例:AddXiHan 返回之后再改 XiHan:* 下的键,要重启才对框架生效。命名存储实例是例外,它的定义在首次取用时才从 XiHan:ObjectStorage:Stores:<name> 读取(见对象存储)。

AddXiHan 在调用时就求解能力图谱、解析绑定、装配全部特性,所以远程配置、密钥这类配置源必须在 AddXiHan 之前加入 builder.Configuration,否则框架的选项与绑定读不到它们。

配置节命名 ​

框架的配置节一律以 XiHan:<领域> 开头,领域词取自规范术语表(Kernel、Persistence、Caching、Localization、ObjectStorage、Configuration 等)。实现包的配置在领域节下再加一段实现名,例如 XiHan:Caching:Redis、XiHan:ObjectStorage:FileSystem;领域节本身放抽象层的选项,例如 XiHan:Localization:DefaultLocale。特性清单的 Contributes.Config 声明它在本领域里读取的配置的最近公共节:只读自己子节的写子节(Caching.Hybrid 写 XiHan:Caching:Hybrid),同时读领域节下的公共选项的写领域节(Caching.Redis 还读 XiHan:Caching:Idempotency,写 XiHan:Caching),见 RFC-0002「配置节」。

写法例子
JSON{ "XiHan": { "Kernel": { "StopTimeoutSeconds": 25 } } }
配置键XiHan:Kernel:StopTimeoutSeconds
环境变量XiHan__Kernel__StopTimeoutSeconds=25

时长类的键带单位后缀(StopTimeoutSeconds、RefreshIntervalSeconds、MultipartExpiryHours),在代码里对应 TimeSpan 属性。值不合法(负数、无法解析的枚举或布尔值)时 FromConfiguration 抛出 ArgumentException,应用在启动期失败。

应用自己的配置节用自己的名字,不放进 XiHan 下,例如 KubernetesApp 示例的 Sample。

应用自己的选项 ​

应用的选项照常用 IOptions<T> / IOptionsMonitor<T> 绑定。需要随配置文件变化而更新的值,注入 IOptionsMonitor<T> 并读 CurrentValue。下面的代码取自 KubernetesApp 示例,略去了与配置无关的部分:

csharp
// BannerOptions.cs
namespace KubernetesApp;

public sealed class BannerOptions
{
    public const string Section = "Sample";

    public string Banner { get; set; } = "Hello from XiHan";
}
csharp
// Program.cs
using KubernetesApp;
using Microsoft.Extensions.Options;
using XiHan.Framework.Hosting.AspNetCore;
using XiHan.Framework.Profiles.Full;

var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<BannerOptions>(builder.Configuration.GetSection(BannerOptions.Section));

// AddXiHan 先装载 XIHAN_CONFIG_PATH 目录里的 JSON 文件并监听变化
builder.AddXiHan(xihan => xihan.UseFullProfile());

var app = builder.Build();
app.UseXiHan();

// 挂载文件里的 Sample:Banner 改了,CurrentValue 随之变化,不必重启
app.MapGet("/", (IOptionsMonitor<BannerOptions> banner) => banner.CurrentValue.Banner);

app.Run();
json
{
  "Sample": {
    "Banner": "Hello from appsettings.json"
  }
}

挂载的配置目录与热更新 ​

环境变量 XIHAN_CONFIG_PATH 指向一个目录时(Kubernetes 里是 ConfigMap 的挂载点),Hosting.AspNetCore 与 Hosting.CommandLine 的 AddXiHan 把其中的 JSON 文件作为配置源插在 appsettings.{环境}.json 之后,并以 reloadOnChange: true 监听变化。找文件的规则在内核的 ConfigurationDirectory.Resolve:

  1. 只取目录顶层的 *.json,跳过以 . 开头的条目(ConfigMap 挂载工具放置的 ..data 等)。
  2. appsettings.json 最先装载,其余文件按文件名的序数顺序随后装载,后装载的覆盖先装载的同名键。
  3. 目录不存在或环境变量为空时什么都不加。

这些文件紧接构建器里最后一个 appsettings 文件源(appsettings.json 或 appsettings.{环境}.json)插入。WebApplication.CreateBuilder 与 Host.CreateApplicationBuilder 的配置源因此从低到高是:

顺序配置源
1appsettings.json
2appsettings.{环境}.json
3XIHAN_CONFIG_PATH 目录里的 JSON 文件
4用户机密(仅开发环境)
5环境变量
6命令行参数
7应用自己添加的配置源(远程配置、密钥等),按添加顺序

后者覆盖前者:挂载文件覆盖 appsettings;同一个键同时出现在挂载文件与环境变量里时,环境变量的值生效。xihan pack 用环境变量写的 XiHan__Kernel__StopTimeoutSeconds 因此不会被 ConfigMap 里的同名键改掉。构建器里没有 appsettings 文件源(应用关掉了默认配置)时,目录里的文件追加在末尾。文件列表在启动时确定,运行中新增的文件要重启才装载;已装载文件的内容变化会触发 IConfiguration 的重载令牌,IOptionsMonitor<T> 随之更新。

ConfigMap 更新要用轮询监视

kubelet 更新 ConfigMap 时切换的是符号链接,默认的文件系统通知收不到变化。容器里要设 DOTNET_USE_POLLING_FILE_WATCHER=1;xihan pack 按应用清单的 config 生成 ConfigMap 时会一并写入它与 XIHAN_CONFIG_PATH(挂载点缺省 /etc/xihan)。

热更新只作用于读 IConfiguration 或 IOptionsMonitor<T> 的代码。框架包的选项在装配时已经读完,改挂载文件里的 XiHan:* 键不会改变正在运行的特性。部署侧的生成规则见部署与打包。

资源绑定 ​

特性需要的外部资源(数据库连接、Redis、消息代理、对象存储端点)在清单的 Bindings 里按名字声明,宿主在装配时解析出 BindingValue(名字、类型、主值与其余属性),特性用 context.GetBinding(name) 或 context.TryGetBinding(name) 取用。这样同一个能力包在本地、Compose 与 Kubernetes 里不改代码,只换绑定的来源。

内核的 BindingResolver.Resolve 按下面的顺序收集绑定:

  1. 环境变量 SERVICE_BINDING_ROOT 指向的目录(Service Binding 规范)。每个子目录是一个绑定,目录名是绑定名;目录里每个文件是一个属性,文件名是属性名、内容修剪首尾空白后是值;type 文件是类型,uri 文件既是主值也保留为属性;以 . 开头的文件跳过。AppBuilder.UseServiceBindingRoot(directory) 可以在代码里改用别的目录。
  2. 配置节 XiHan:Bindings:<name>。节本身的标量值或子键 value 是主值,子键 type 是类型,其余子键是属性。

同名时配置整体覆盖目录来源,不逐属性合并。

json
{
  "XiHan": {
    "Bindings": {
      "cache": "localhost:6379",
      "db": {
        "type": "connection:relational",
        "value": "Host=localhost;Database=orders;Username=dev;Password=dev-password"
      }
    }
  }
}

环境变量写法是 XiHan__Bindings__db__value、XiHan__Bindings__db__type,Compose 与 Aspire 的生成产物就是这样注入的。

清单里 required: true 的绑定在 AddXiHan 构建时校验:缺失,或来源声明了类型而与清单不一致,都抛出 KERNEL_HOSTING_001,应用不会启动。来源没有声明类型(空字符串)时不比对类型。可选绑定由特性自己用 TryGetBinding 处理。

框架内置包声明的绑定都是可选的。绑定来自部署环境,给出的连接信息(主值)与凭据(下表的属性)逐项覆盖 Provider 配置节里的同类键:绑定里有这一项就用绑定的,没有就读配置节的;前缀、超时、分组等不是连接与凭据的键照读配置节。绑定的主值或属性为空白时不算给出;凭据属性与主值互不依赖,绑定只给凭据、连接来自配置节也照样覆盖凭据;两者都没有连接时装配失败。属性名区分大小写,按表里的写;凭据不进日志与错误消息(RFC-0016「资源绑定与配置节」):

绑定名类型声明它的包用法
dbconnection:relationalPersistence.EntityFrameworkCore、Persistence.SqlSugar交给应用传入特性的配置委托,主值是连接字符串
cachecache:distributedCaching.Redis主值覆盖 XiHan:Caching:Redis:Configuration;属性 username、password 覆盖连接字符串里的 user、password
queuequeueMessaging.RabbitMQ主值覆盖 XiHan:Messaging:RabbitMQ:Configuration;属性 username、password 覆盖 AMQP URI 里的用户名与密码
streamstreamMessaging.Kafka主值覆盖 XiHan:Messaging:Kafka:BootstrapServers;属性 security.protocol、sasl.mechanism、sasl.username、sasl.password 覆盖 Properties 里的同名键(只认这四项)
nacosconfiguration:remoteConfiguration.Nacos主值覆盖 XiHan:Configuration:Nacos:ServerAddresses;属性 username、password 覆盖 Username、Password
objectstorageblobObjectStorage.S3主值(服务端点)与属性 region、accessKey、secretKey、forcePathStyle 覆盖 XiHan:ObjectStorage:S3 里的同名设置

表里六种绑定类型 xihan pack 都认识:应用清单 xihan.app.json 按上表的绑定名声明后,Compose 与 Aspire 产物会起对应的依赖服务并把主值注入 XiHan__Bindings__<绑定名>__value(blob 的依赖服务是 S3 兼容的 RustFS,另注入 accessKey、secretKey 两个属性,其余服务的凭据在主值里或没开认证),Kustomize 产物不在集群里起依赖服务(Kafka、Nacos 也不起),只按 Service Binding 规范挂 Secret,示例 Secret 以注释列出各类型可单独给出的凭据键(见部署)。

应用自己的特性声明绑定的写法:

csharp
using Microsoft.Extensions.DependencyInjection;
using XiHan.Framework.Kernel;
using XiHan.Framework.Kernel.Hosting;
using XiHan.Framework.Primitives;
using XiHan.Framework.Primitives.Manifests;

namespace Billing;

public sealed class BillingFeature : IFeature
{
    public Manifest Manifest { get; } = new()
    {
        Id = "xihan.billing.ledger",
        Package = "Billing",
        Version = "1.0.0",
        Primitives = 1,
        Stability = Stability.Experimental,
        Kind = ManifestKind.Capability,
        Requires = [new CapabilityRequirement(KernelCapabilities.Hosting, KernelCapabilities.Version)],
        // 必需绑定:缺失时 AddXiHan 抛出 KERNEL_HOSTING_001,启动前就暴露
        Bindings = [new Binding("ledger", "connection:relational")],
        Entry = typeof(BillingFeature).FullName,
    };

    public void Configure(FeatureContext context)
    {
        var ledger = context.GetBinding("ledger");
        context.Services.AddSingleton(new LedgerConnection(ledger.Value ?? throw new InvalidOperationException("Binding 'ledger' has no value.")));
    }
}

public sealed record LedgerConnection(string ConnectionString);

清单字段与能力声明的完整说明见能力包与清单。

远程配置 ​

configuration.remote@1 的契约是 IRemoteConfigurationClient.FetchAsync(namespace, knownVersion):按命名空间取整份带版本的文档 ConfigurationDocument,键已经展平成 A:B:C 形式;knownVersion 非空且远端没有变化时返回无值,实现可以长轮询。AddXiHanRemoteConfiguration(client, options) 把客户端接进配置:

  1. 构建配置时同步加载一次。IConfigurationProvider.Load 是同步契约,取值在线程池上执行并等待,受 LoadTimeout(缺省 10 秒)约束。
  2. 首次加载失败——客户端返回失败结果、超过 LoadTimeout(CONFIGURATION_UNAVAILABLE_001,原因 load timeout)或客户端抛出异常(同一个码,原因是异常消息)——时先回调 OnError;Optional 为 false(缺省)时随后抛出带错误码的 FrameworkException(客户端抛出的异常是它的内部异常),启动失败,为 true 时该源为空。
  3. 不论首次加载成败,之后都按 PollInterval(缺省 30 秒,null 关闭轮询)带已知版本轮询;首次失败时已知版本为空,第一次成功的轮询装入整份文档。拿到新版本就整体替换这个源的数据并触发重载令牌,IOptionsMonitor<T> 随之更新。
  4. 轮询失败(返回失败结果或抛出异常)只回调 OnError,保留最后一份成功的数据。

客户端的归属看用哪个重载:AddXiHanRemoteConfiguration(client, options) 传入的客户端由调用方持有,配置根释放时不释放它;AddXiHanRemoteConfiguration(clientFactory, options) 每次构建 Provider 按工厂新建一个客户端,配置根释放时随之释放(实现 IDisposable 时)。配置构建期自建、没有别人持有的客户端用工厂重载。

Prefix 把文档挂到某个配置节下,为空时挂在根。OnError 是唯一的报告渠道,因为配置在日志之前构建;回调自己抛出的异常被丢弃,不改变首次加载的结果,也不终止轮询。

选项类型缺省说明
Namespacestring构造参数远程命名空间,Nacos 里是 dataId
Prefixstring?null挂载的配置节
PollIntervalTimeSpan?30 秒轮询周期,null 关闭,必须为正
ClockTimeProvider系统时钟轮询计时用的时钟;测试换成可推进的时钟(如 FakeTimeProvider),轮询由用例触发
LoadTimeoutTimeSpan10 秒首次加载的超时,必须为正
Optionalboolfalse首次加载失败时是否继续启动(该源为空,照常轮询)
OnErrorAction<Error>?null加载或轮询失败时的回调,它抛出的异常被丢弃

Nacos ​

框架提供的远程配置 Provider 是 Configuration.Nacos:直接调用 Nacos 的 HTTP 配置接口(v1,与 Nacos 2.x 兼容),命名空间参数就是 dataId,版本是服务端给出的内容 MD5,knownVersion 非空时先长轮询监听,服务端报告变化才取整份文档。下面把 dataId 为 orders 的 JSON 文档挂到 Orders 节下,服务地址等连接设置从 XiHan:Configuration:Nacos 读:

csharp
using XiHan.Framework.Configuration.Abstractions.Remote;
using XiHan.Framework.Configuration.Nacos;
using XiHan.Framework.Hosting.AspNetCore;
using XiHan.Framework.Profiles.Standard;

var builder = WebApplication.CreateBuilder(args);

// 必须在 AddXiHan 之前:框架在 AddXiHan 里读取选项与绑定
builder.Configuration.AddXiHanNacos(
    NacosOptions.FromConfiguration(builder.Configuration),
    new RemoteConfigurationOptions("orders")
    {
        Prefix = "Orders",
        PollInterval = TimeSpan.FromSeconds(15),
        OnError = static error => Console.Error.WriteLine($"Nacos: {error.Code}"),
    });
builder.Services.Configure<OrderLimits>(builder.Configuration.GetSection("Orders"));

builder.AddXiHan(xihan => xihan.UseStandardProfile());

var app = builder.Build();
app.UseXiHan();
app.Run();

public sealed class OrderLimits
{
    public int MaxItems { get; set; } = 100;
}
json
{
  "XiHan": {
    "Configuration": {
      "Nacos": {
        "ServerAddresses": "http://localhost:8848",
        "Group": "DEFAULT_GROUP",
        "Format": "Json"
      }
    }
  }
}

AddXiHanNacos 经工厂重载自建客户端(自带 HTTP 客户端),用在配置构建期,随配置根释放。另装 NacosConfigurationFeature 时,运行期容器里会登记 IRemoteConfigurationClient,供其他组件按需取文档。连接选项、长轮询与登录的细节见包页。

密钥 ​

configuration.secrets@1 的契约是 ISecretStore.GetAsync(names[]):按名字批量读取,只读,逐项返回 SecretLookup(Name, Result<SecretValue>),顺序与入参一致,重复项各自作答,空集合返回空。写入与轮换属于运维工具,不在应用契约里。

  • 密钥名 SecretName 的文法是 ^[A-Za-z0-9][A-Za-z0-9._/-]{0,255}$,不含 .. 与 //,不以 / 结尾,大小写敏感;不合法在构造时抛出 ArgumentException。
  • SecretValue.ToString() 固定返回 ***(SecretValue.Redacted),值不会经字符串插值进入日志或异常消息。读值用 Value。
  • 单条读取用扩展方法 store.GetAsync(name, cancellationToken),它转调批量方法。

AddXiHanSecrets(store, options) 把密钥映射到配置键:Mappings 是配置键到密钥名的字典,构建配置时一次批量读取。失败分两类:逐项失败(不存在、无权限等)每项回调一次 OnError;整体失败——超过 LoadTimeout、密钥库抛出异常、返回的条数与请求不一致——回调一次 CONFIGURATION_UNAVAILABLE_002。首次读取有失败时,Optional 为 false(缺省)随后抛出 FrameworkException(逐项失败列出失败的配置键,密钥库抛出的异常是它的内部异常),为 true 时跳过失败的项,整体失败时该源为空。不论首次读取成败,RefreshInterval 非空时都周期性重读:逐项失败的项保留旧值,整体失败保留全部旧值并回调。OnError 自己抛出的异常同样被丢弃,不终止重读。

选项类型缺省说明
MappingsIReadOnlyDictionary<string, SecretName>构造参数配置键 → 密钥名,至少一项
LoadTimeoutTimeSpan10 秒首次读取的超时
RefreshIntervalTimeSpan?null周期重读的间隔,null 不重读
ClockTimeProvider系统时钟重读计时用的时钟;测试换成可推进的时钟,重读由用例触发
Optionalboolfalse首次读取缺失或失败的项是否跳过(整体失败时该源为空,照常重读)
OnErrorAction<Error>?null每个失败的项回调一次,整体失败回调一次,它抛出的异常被丢弃

框架没有提供密钥库 Provider(Vault、Key Vault 等),应用按自己的密钥来源实现 ISecretStore,并让测试项目继承 Configuration.Conformance 的 SecretStoreConformance 验证语义。下面的实现从一个目录读文件,每个密钥一个文件:

csharp
using XiHan.Framework.Configuration.Abstractions;
using XiHan.Framework.Configuration.Abstractions.Secrets;
using XiHan.Framework.Primitives;

namespace Orders.Secrets;

public sealed class DirectorySecretStore(string root) : ISecretStore
{
    public async ValueTask<IReadOnlyList<SecretLookup>> GetAsync(IReadOnlyList<SecretName> names, CancellationToken cancellationToken)
    {
        var results = new List<SecretLookup>(names.Count);
        foreach (var name in names)
        {
            cancellationToken.ThrowIfCancellationRequested();
            // SecretName 的文法已排除 ".." 与开头的 "/",拼出的路径不会跳出根目录
            var path = Path.Combine(root, name.Value);
            Result<SecretValue> result;
            try
            {
                result = File.Exists(path)
                    ? new SecretValue((await File.ReadAllTextAsync(path, cancellationToken)).Trim())
                    : Error.NotFound(ConfigurationErrors.SecretNotFound, ConfigurationMessages.SecretNotFound, MessageArguments.Of(("name", name.Value)));
            }
            catch (IOException exception)
            {
                result = Error.Unavailable(ConfigurationErrors.SecretsUnavailable, ConfigurationMessages.SecretsUnavailable, MessageArguments.Of(("reason", exception.Message)));
            }

            results.Add(new SecretLookup(name, result));
        }

        return results;
    }
}
csharp
// Program.cs:密钥源同样要在 AddXiHan 之前加入,绑定 db 的主值才能取到它
builder.Configuration.AddXiHanSecrets(
    new DirectorySecretStore("/run/secrets"),
    new SecretsConfigurationOptions(new Dictionary<string, SecretName>
    {
        ["XiHan:Bindings:db:value"] = "orders/db-connection",
    })
    {
        RefreshInterval = TimeSpan.FromMinutes(5),
    });

选项打印时遮蔽凭据 ​

框架的选项与携带凭据的记录在 ToString() 里把凭据打印成 ***(Redaction.Mask),值为 null 时打印为空,看得出有没有配置、看不到值;访问密钥 ID(S3 的 AccessKey)是访问密钥的一半,同样遮蔽;与口令同在一个记录里的登录用户名(Redis 的 User、RabbitMQ 的 UserName、Nacos 的 Username)是登录凭据的另一半,也遮蔽(ADR-0090);端点与令牌文件路径照常打印,排查连接问题要用到它们,要核对连的是哪个用户,直接读选项对象的属性。不带凭据的记录里的用户名(如观测的 RuntimeInfo.UserName,运行进程的系统账户)照常打印;持久化驱动异常消息里连接串的 Username= / User Id= 也照常保留——用户名的遮蔽到此为止,已定(ADR-0093,维持 ADR-0084)。连接串整串遮蔽,与持久化驱动消息的脱敏范围一致(只遮整串连接串与口令类的值)。字典与列表照记录的缺省只打印类型名,不展开内容。

记录遮蔽的成员
RedisCachingOptionsConfiguration(连接字符串)、User、Password
RabbitMQMessagingOptionsConfiguration(AMQP URI)、UserName、Password
NacosOptionsUsername、Password
S3ObjectStorageOptionsAccessKey(访问密钥 ID)、SecretKey
AIProviderOptionsApiKey
KubernetesSchedulingOptionsToken
JwtOptionsSecret
HostedBlobUrlOptionsSecret
PrincipalRecord(Security.InMemory)ApiKey
TenantShardConnectionString
BindingValueValue(绑定的主值)

应用自己的选项若是记录且带凭据,照样手写 PrintMembers 并用 Redaction.Redact,参考上表各类型的写法。

进入 IConfiguration 的密钥是明文

遮蔽只作用于 SecretValue 对象与上表记录的 ToString()。映射进配置之后,configuration["XiHan:Bindings:db:value"] 返回的是原始字符串;不要把整个配置节序列化进日志或诊断端点。

失败与错误码 ​

错误码含义出现在
KERNEL_HOSTING_001必需绑定缺失或类型不匹配AddXiHan 构建时、FeatureContext.GetBinding
CONFIGURATION_NOTFOUND_001远程配置的命名空间不存在IRemoteConfigurationClient.FetchAsync
CONFIGURATION_NOTFOUND_002密钥不存在ISecretStore.GetAsync 的逐项结果
CONFIGURATION_UNAVAILABLE_001远程配置不可达或超时(首次加载超时、客户端抛出异常也归此类)IRemoteConfigurationClient.FetchAsync、首次加载
CONFIGURATION_UNAVAILABLE_002密钥库不可达或超时(密钥库抛出异常、返回条数与请求不一致也归此类)ISecretStore.GetAsync、首次读取
CONFIGURATION_DENIED_001没有读取该密钥的权限ISecretStore.GetAsync 的逐项结果
CONFIGURATION_VALIDATION_001远程文档不是声明的格式IRemoteConfigurationClient.FetchAsync

远程配置与密钥的首次加载失败且不可选时,FrameworkException 的错误码就是上表里对应的码,客户端或密钥库抛出的异常是它的内部异常;轮询与重读的失败只经 OnError 报告。选项值不合法、密钥名或命名空间为空属于编程错误,构造时抛出 ArgumentException。

配置节一览 ​

下表列出各包在代码里读取的配置节(ConfigurationSection 常量与 FromConfiguration 读取的键)。XiHan:Providers:<能力 ID> 指定某个能力由哪份清单提供,原理见能力包与清单。

配置节所属包用途
XiHan:ProvidersKernel<能力 ID> → 清单 ID,指定能力的提供者
XiHan:BindingsKernel资源绑定,见上文「资源绑定」
XiHan:KernelKernelStartTimeoutSeconds、StopTimeoutSeconds、FailurePolicy、UseBuiltInMiddleware
XiHan:Kernel:ResilienceKernelResilience 阶段的默认策略,Operations:<操作 ID> 按操作覆盖
XiHan:Persistence:InMemoryPersistence.InMemoryMaxEntitiesPerType
XiHan:Persistence:EntityFrameworkCorePersistence.EntityFrameworkCoreEnsureCreated、HealthProbeIntervalSeconds
XiHan:Persistence:SqlSugarPersistence.SqlSugarInitTables、CommandTimeoutSeconds、Replicas:*(从库的权重与健康探测)、HealthProbeIntervalSeconds
XiHan:Persistence:SnowflakePersistence.Abstractions雪花标识:WorkerId、Epoch、LeaseTimeToLiveSeconds、ClockDriftToleranceMilliseconds
XiHan:MultiTenancyMultiTenancy.AbstractionsDefaultTenant、RequireTenant、TenantClaim、ValidateAgainstStore
XiHan:MultiTenancy:InMemoryMultiTenancy.InMemoryMaxTenants
XiHan:MultiTenancy:TenantsMultiTenancy.InMemory从配置装载的租户(DisplayName、IsEnabled、Properties)
XiHan:MultiTenancy:DatabaseMultiTenancy.DatabaseCacheSize、CacheTimeToLiveSeconds、MaxListedTenants
XiHan:SecuritySecurity.AbstractionsRequireAuthentication、RoleClaim
XiHan:Security:OutboundKernel出站地址策略:AllowLoopback、AllowPrivateNetwork、AllowedNetworks、AllowedHosts
XiHan:Security:InMemorySecurity.InMemory开发用主体与授予(Principals、Grants)
XiHan:Security:DatabaseSecurity.DatabaseCacheSize、CacheTimeToLiveSeconds
XiHan:Security:JwtSecurity.JwtIssuer、Audience、Secret、ClockSkewSeconds、NameClaim
XiHan:Security:OpenIdConnectSecurity.OpenIdConnectAuthority、Audience、元数据地址与刷新间隔
XiHan:Security:Ip2RegionSecurity.Ip2Regionxdb 数据文件路径 V4Database、V6Database
XiHan:Caching:InMemoryCaching.InMemoryMaxEntries、DefaultTimeToLiveSeconds
XiHan:Caching:RedisCaching.RedisConfiguration、KeyPrefix、DefaultTimeToLiveSeconds、PublishChanges、HealthProbeIntervalSeconds
XiHan:Caching:HybridCaching.HybridLocalCapacity、LocalTimeToLiveSeconds
XiHan:Caching:RemoteCaching.RemoteTimeoutMilliseconds
XiHan:Caching:IdempotencyCaching.Abstractions幂等记录的 TimeToLiveSeconds、InProgressTimeToLiveSeconds
XiHan:MessagingMessaging.AbstractionsMaxAttempts、DeadLetterSuffix、InstanceId
XiHan:Messaging:OutboxMessaging.Abstractions发件箱的 PollIntervalSeconds、BatchSize、MaxAttempts、RetryDelaySeconds、MaxRetryDelaySeconds、DispatchedRetentionSeconds
XiHan:Messaging:InMemoryMessaging.InMemoryMaxQueuedMessages
XiHan:Messaging:RabbitMQMessaging.RabbitMQConfiguration、QueuePrefix、PrefetchCount、HealthProbeIntervalSeconds
XiHan:Messaging:KafkaMessaging.KafkaBootstrapServers、GroupId、TopicPrefix、HealthProbeIntervalSeconds、RedeliveryDelaySeconds、Properties:<key>
XiHan:SchedulingScheduling.Abstractions调度引擎与领导选举:轮询、租约、并发、错过阈值、历史保留
XiHan:Scheduling:InMemoryScheduling.InMemoryMaxRuns
XiHan:Scheduling:DatabaseScheduling.DatabaseHealthProbeIntervalSeconds
XiHan:Scheduling:KubernetesScheduling.KubernetesLease 选举:Lease、Namespace、Holder、ApiServer
XiHan:WorkflowWorkflow.Abstractions引擎:锁超时、子流程深度、表达式缓存、保留天数
XiHan:Workflow:InMemoryWorkflow.InMemory各存储容量、轮询周期与批大小
XiHan:Workflow:DatabaseWorkflow.Database到期书签的轮询与批大小、租约时长、HolderId
XiHan:LocalizationLocalization.AbstractionsDefaultLocale、Locales
XiHan:Localization:DatabaseLocalization.DatabaseRefreshIntervalSeconds、MaxTranslations
XiHan:ObjectStorage:FileSystemObjectStorage.FileSystemRootPath、MaxTotalBytes、MaxBlobBytes、MultipartExpiryHours
XiHan:ObjectStorage:S3ObjectStorage.S3ServiceUrl、Region、AccessKey、SecretKey、ForcePathStyle 等
XiHan:ObjectStorage:StoresObjectStorage.Abstractions命名存储实例:<name>:Provider 加该 Provider 的设置
XiHan:ObjectStorage:StoreHealthProbeIntervalSecondsObjectStorage.Abstractions命名实例健康探测的间隔(单个键)
XiHan:ObjectStorage:SignedUrlsHosting.AspNetCore宿主代收发预签名地址的 BaseUrl、Secret
XiHan:Configuration:NacosConfiguration.NacosNacos 服务地址、分组、命名空间、登录与超时
XiHan:AuditingAuditing.AbstractionsSelection、IncludeSuccesses
XiHan:Auditing:InMemoryAuditing.InMemoryCapacity、LogEvents
XiHan:Auditing:DatabaseAuditing.DatabaseQueueCapacity、BatchSize、FlushIntervalSeconds、LogEvents
XiHan:Observability:HostObservability.HostSampleIntervalSeconds
XiHan:Observability:OpenTelemetryObservability.OpenTelemetry服务名、追踪、指标、日志、采样与 OTLP 导出
XiHan:AIAI.AbstractionsProvider 表、工具名、护栏、知识库与提示词
XiHan:Protocols:HttpProtocols.HttpRoutePrefix,Routes:<操作 ID> 覆盖推导的路由
XiHan:Protocols:GrpcProtocols.GrpcPackage,Methods:<操作 ID> 覆盖推导的方法名
XiHan:Protocols:McpProtocols.McpServerName、ServerVersion、Instructions,Tools:<操作 ID>
XiHan:Protocols:CloudEventsProtocols.CloudEventsInbound、Outbound、Topics:<事件类型>、Webhooks:<主题>
XiHan:Plugins:OutOfProcessPlugins.OutOfProcess插件目录、授予、握手与启停超时、健康与重启限制
XiHan:Plugins:WasmPlugins.Wasm插件目录、授予、挂载、内存与栈上限、调用超时

各键的类型与缺省值以对应包页为准。

相关 ​

Released under The MIT License