配置参考
appsettings 的全量配置节说明。所有键名与默认值对照仓库里的 appsettings.Development.json 与各 Options 类核实。
文件与优先级
backend/src/main/XiHan.BasicApp.WebHost/
├── appsettings.json # 基础(Logging / AllowedHosts / CodeGeneration)
├── appsettings.Development.json # 开发环境(完整示例,带逐项注释)
└── appsettings.Production.json # 生产环境(被 .gitignore 忽略,仓库里没有,部署处自建)优先级(后者覆盖前者):appsettings.json → appsettings.{Environment}.json → 环境变量 → 命令行。
环境变量写法
配置层级用双下划线表示:XiHan:Authentication:Jwt:SecretKey → XiHan__Authentication__Jwt__SecretKey。
生产的密钥类配置一律走环境变量或密钥库,不要提交明文。 生产 appsettings 通常被 gitignore,需要在服务器上单独维护——这也是几个开关(如 EnableDiffLog)最容易漏配的原因。
Hosting
| 键 | 说明 | 示例 |
|---|---|---|
Urls | 监听地址与端口,多个用分号分隔 | http://127.0.0.1:9708 |
appsettings.Development.json 与 Development launch profile 都是 9708;Production launch profile 的 applicationUrl 为 9709,仓库不含 appsettings.Production.json,部署处写入 Hosting:Urls 后以它为准。Docker 镜像通过环境变量 Hosting__Urls 在容器内监听 9708,宿主机端口可由 Compose 的 BACKEND_PORT 覆盖。开发环境改端口后要同步修改前端的 VITE_DEV_PROXY_TARGET。
XiHan:Observability
链路追踪(OpenTelemetry)。
| 键 | 默认 | 说明 |
|---|---|---|
Enabled | false | 总开关。开启后每请求产生 W3C Activity,TraceId 变 32-hex,日志/审计/事件总线统一同源;关则退回 Kestrel TraceIdentifier |
ServiceName | — | 写入 OTel Resource 的 service.name |
SamplingRatio | — | 采样率 0~1,开发可设 1.0 全采 |
ConsoleExporter | false | 控制台打印 span(调试用) |
OtlpEndpoint | "" | OTLP 导出端点(如 http://localhost:4317)。为空则只在本地产生 TraceId,不外发到 Jaeger/Tempo |
XiHan:DistributedIds:SnowflakeId
雪花 ID 生成器。
| 键 | 说明 |
|---|---|
WorkerId | 同一集群内每个节点必须唯一,否则生成重复 ID。多节点部署务必逐节点改 |
DataCenterId | 多机房区分,单机房固定即可 |
BaseTime | 起始纪元,一经上线不可更改(改动会导致 ID 回退甚至冲突) |
WorkerIdBitLength | 机器码位长,与序列号位长之和不超过 22。6 位 → WorkerId 上限 0-63 |
SeqBitLength | 序列号位长,决定同毫秒并发上限,一经上线不可更改 |
SnowflakeIdType | SnowFlakeMethod(漂移算法,抗时钟回拨、吞吐更高)/ ClassicSnowFlakeMethod |
多节点必改 WorkerId
这是最容易忽略、后果最严重的一项:两个节点同 WorkerId 会生成重复主键,且不会立刻报错,等到唯一约束冲突时数据已经乱了。
XiHan:Authentication
PasswordHasher(PBKDF2)
| 键 | 默认 | 说明 |
|---|---|---|
Version | 1 | 哈希方案版本,用于将来平滑升级算法(老密码按旧版本校验) |
Iterations | 600000 | 迭代次数,OWASP 对 PBKDF2-SHA256 的推荐量级 |
SaltSize / HashSize | 32 / 32 | 盐与输出长度(字节) |
HashAlgorithm | SHA256 | — |
Jwt
| 键 | 默认 | 说明 |
|---|---|---|
SecretKey | — | 签名密钥,生产务必改为高强度随机值并保密(走环境变量/密钥库) |
Issuer / Audience | — | 签发者 / 受众 |
AccessTokenExpirationMinutes | 60(框架默认) | 访问令牌有效期 |
RefreshTokenExpirationDays | 7 | 刷新令牌有效期 |
ClockSkewMinutes | 5 | 允许的时钟偏差,容忍多节点时间误差 |
仓库的 Development 配置把
AccessTokenExpirationMinutes设为120,以实际配置为准。
OAuth(第三方登录)
| 键 | 说明 |
|---|---|
Enabled | 总开关 |
FrontendCallbackUrl | 登录成功后跳回的前端回调页 |
Providers[] | 各提供商:Name(内部标识,勿改)、DisplayName、Enabled、ClientId、ClientSecret、Scopes[] |
内建 github / gitee / google / qq,需到对应平台申请后替换 ClientId / ClientSecret。
XiHan:Data:SqlSugarCore
连接
ConnectionConfigs[] 每项:
| 键 | 说明 |
|---|---|
ConfigId | 连接唯一标识(多库/多租户路由用),字符串 |
ConnectionString | 主库连接串 |
DbType | PostgreSQL / MySql / SqlServer / Sqlite / Oracle / Dm / Kdbndp 等;独立库租户与升级脚本的支持范围见数据库配置 |
IsAutoCloseConnection | 是否自动关闭连接 |
SlaveConnectionConfigs[] | 从库(读写分离);空数组=单库 |
配了从库后 SELECT 自动走从库、写与事务走主库,业务无感知。
HitRate 配不上
HitRate(读权重)是 SqlSugar 的字段、绑不上 appsettings,写了也无效、恒为 0。框架会把权重为 0 的从库归一化为 DefaultSlaveHitRate(默认 10),所以不写也能等权分担读。
需要差异化权重、挂 ConfigureExternalServices 或自写探活,用代码钩子 XiHanSqlSugarCoreOptions.ConfigureConnectionConfigs。
日志与诊断
| 键 | 默认 | 说明 |
|---|---|---|
EnableSqlLog | false | 打印所有 SQL(生产建议关闭,日志会爆量) |
EnableSqlErrorLog | true | 记录 SQL 异常 |
EnableSlowSqlLog | true | 记录慢 SQL |
SlowSqlThresholdMilliseconds | — | 慢 SQL 阈值,纯观测用途、不影响语句执行 |
CommandTimeoutSeconds | 300 | ADO 命令超时,0/负值不覆盖;须明显大于慢 SQL 阈值 |
初始化
| 键 | 说明 |
|---|---|
EnableDbInitialization | 启动时自动建库(库不存在则创建) |
EnableTableInitialization | 启动时 CodeFirst 建表 |
EnableDataSeeding | 启动时写入种子数据 |
建表只建不改
DbInitializer 表存在就跳过、从不为已有表补列。给既有实体加字段后,存量库必须通过前向 UpdateScripts(或部署流程中的等价迁移步骤)执行 ALTER TABLE。XiHan:Upgrade:EnableAutoCheckOnStartup 为 true 时启动会自动执行这些脚本(开着数据库初始化时排在建表之后、播种之前),见升级与迁移。
EnableDiffLog
| 键 | 默认 | 说明 |
|---|---|---|
EnableDiffLog | false | 实体差异日志(SysDiffLog)总开关 |
数据变更日志页恒空的头号原因
默认是 false——不开则 Diff AOP 根本不挂载,收集到的差异被直接丢弃。生产 appsettings 常被 gitignore,最容易漏配的就是这一项。
代价:开启后 update/delete 会先查一次旧值算差异,每个写操作多一次 SELECT。且只覆盖走仓储的写,绕过仓储直接用 DbClient 的写(如 UpdateColumns)不产生差异日志。
从库健康探针
| 键 | 默认 | 说明 |
|---|---|---|
DefaultSlaveHitRate | 10 | 从库权重归一化默认值 |
EnableSlaveHealthCheck | false | 周期探活,不可用从库自动摘除读权重 |
SlaveHealthCheckIntervalSeconds | 30 | 探测周期 |
SlaveFailureCooldownSeconds | 120 | 故障冷却窗口,恢复后先冷却再回填权重避免抖动 |
XiHan:Caching:Redis
| 键 | 默认 | 说明 |
|---|---|---|
IsEnabled | — | 关闭则退化为进程内内存缓存(失去分布式缓存/锁/队列) |
Configuration | — | 连接串 host:port,user=,password=,defaultDatabase= |
InstanceName | XiHan: | 缓存 Key 统一前缀(隔离不同应用/环境) |
ConnectTimeout / SyncTimeout / AsyncTimeout | 5000 | 各类超时(毫秒) |
AllowAdmin | false | 允许管理类命令(FLUSHDB/CONFIG),生产慎开 |
UseSsl | false | — |
AbortOnConnectFail | false | false = 后台持续重连,更适合生产 |
关掉 Redis 的连锁反应
IsEnabled=false 时分布式锁退化为进程内锁——多实例部署会各跑各的:定时任务重复执行、后台 Worker 不再单活、工作流定时器多实例并发。单机开发无所谓,生产必须开。
XiHan:Web
Core:ClientInfo
| 键 | 说明 |
|---|---|
EnableIpRegion | 是否启用 IP 归属地解析 |
Ip2RegionDbPath | IPv4 的 ip2region 离线库路径 |
Ip2RegionV6DbPath | IPv6 的 ip2region 离线库路径;文件不存在时 IPv6 地址不解析归属地 |
Api:ForwardedHeaders
受信反向代理:转发头(X-Forwarded-For / Proto / Host)只在请求来自这些代理时才被采信,其余来源带的一律忽略。本机回环始终受信,这里配的是追加项。
| 键 | 默认 | 说明 |
|---|---|---|
KnownProxies | [] | 受信代理的地址,如 10.0.0.5 |
KnownNetworks | [] | 受信代理所在网段(CIDR,主机位须为 0),如 172.18.0.0/16 |
ForwardLimit | 1 | 最多从 X-Forwarded-For 右端剥几层受信代理,多级代理按层数调大 |
地址或网段写错、ForwardLimit 小于 1 时启动失败。代理不在本机时必须配置,否则日志、会话、访问策略与自动封禁看到的客户端 IP 都是代理的地址。
Api:Auth
| 键 | 说明 |
|---|---|
RequireAuthenticatedUser | 全局要求已认证(匿名接口需 [AllowAnonymous] 显式放行) |
SignalRHubPathPrefix | SignalR Hub 路由前缀,默认 /hubs |
Api:Cors
| 键 | 说明 |
|---|---|
AllowedOrigins[] | 允许的来源。携带凭证时不能用 *,必须显式列出 |
AllowAnyOrigin | 与 AllowCredentials 互斥 |
AllowAnyMethod / AllowAnyHeader | — |
AllowCredentials | 是否允许携带 Cookie/Authorization |
ExposedHeaders[] | 额外暴露给前端 JS 读取的响应头 |
PreflightMaxAgeSeconds | 预检结果缓存秒数 |
Api:OpenApiSecurity
开放接口签名/防重放/加密,完整说明见 接口对接指南。
| 键 | 框架默认 | 说明 |
|---|---|---|
IsEnabled | false | 总开关 |
ProtectedPathPrefixes | ["/api"] | 必须覆盖,否则开启后整站接口都要验签。BasicApp 配 ["/api/openapi"] |
IgnoredPathPrefixes | — | 豁免前缀(文档/健康检查等) |
AllowUnsignedRequests | false | 灰度开关:允许未带安全头的请求放行 |
RequireContentSignature | true | 强制校验内容签名 |
EnableReplayProtection | true | 防重放(Nonce 去重) |
TimestampToleranceSeconds / NonceExpireSeconds | 300 | 时间戳容差 / Nonce 存活期 |
MaxRequestBodySize | 2 MiB | 最大请求体 |
EnableResponseEncryption | true | 启用响应加密 |
DefaultSignatureAlgorithm | HMACSHA256 | 也支持 HMACSHA512 / RSASHA256 / SM2 |
DefaultContentSignatureAlgorithm | SHA256 | 也支持 SHA512 |
Clients[] | — | 配置文件里的静态客户端(AccessKey / SecretKey / EncryptKey / IpWhitelist 等)。密钥敏感,生产走环境变量 |
RealTime:SignalR
| 键 | 说明 |
|---|---|
EnableDetailedErrors | 详细错误(生产设 false) |
KeepAliveInterval / ClientTimeoutInterval / HandshakeTimeout | 心跳与超时(hh:mm:ss) |
MaximumReceiveMessageSize | 最大接收消息大小(字节) |
StreamBufferCapacity | 流缓冲容量 |
MaximumParallelInvocationsPerClient | 每客户端最大并行调用数 |
EnableConnectionMetrics | 连接指标 |
Gateway / GrayRouting
| 键 | 说明 |
|---|---|
Gateway.EnableGrayRouting / EnableRequestTracing / EnableRateLimiting / EnableCircuitBreaker | 各能力开关 |
Gateway.RequestTimeoutSeconds | 网关请求超时 |
Gateway.AllowedOrigins[] / GlobalHeaders | 允许来源 / 统一注入的响应头 |
GrayRouting.Rules[] | 灰度规则:RuleType(1=按百分比 2=用户白名单 3=租户 4=请求头)、Priority(越大越优先)、TargetVersion、Configuration(JSON 字符串参数)、IsEnabled |
XiHan:Upgrade
| 键 | 说明 |
|---|---|
MinSupportVersion / AppVersion | 最低来源版本 / 当前版本(留空则运行时探测程序集版本) |
MigrationsRootPath | 迁移脚本根目录 |
LockResourceKey / LockExpirySeconds | 分布式锁(防多节点并发升级) |
EnableAutoCheckOnStartup | 启动时自动执行待执行的升级脚本(缺省 true);失败即中断启动。关掉后启动不改库,须先在发布流程中完成迁移 |
NodeName / PrimaryNodeName | 当前节点 / 仅主节点执行迁移,其余等待 |
EnableMultiTenantIsolation | 是否按租户逐库执行 |
ConnectionConfigId | 升级使用的连接 |
EnableMaintenanceMode | 升级期间进入维护模式 |
EnableFileUpdate / EnableRollingRestart | 文件更新 / 滚动重启 |
版本状态与执行历史分别保存在 SysVersion、SysMigrationHistory,不使用 version.txt。引擎按 UpdateScripts/<版本>/ 的版本顺序处理平台库及配置为独立库的租户,锁租约避免多节点并发;启动时由数据库初始化的升级段(SaasSchemaUpgrader)与升级模块的初始化后钩子调用,完整边界见升级与迁移。当前仓库脚本使用 PostgreSQL SQL,切换数据库提供程序时需要维护对应方言的脚本。
XiHan:Localization
| 键 | 说明 |
|---|---|
ResourcesPath | 资源文件目录 |
DefaultResourceName | 默认资源名 |
DefaultCulture | 默认文化,如 zh-CN |
EnumResourceName | 枚举文案资源名(枚举标签的单一事实源,如 Enums) |
EnableDynamicJsonReload | 资源 JSON 热重载 |
XiHan:ObjectStorage
| 键 | 默认 | 说明 |
|---|---|---|
Local.RootPath | wwwroot/uploads | 文件落盘根目录;这是 BasicApp 的显式配置,不是 Framework LocalStorageOptions 的默认值(wwwroot/Uploads) |
Local.UrlPrefix | /uploads | 对外访问 URL 前缀(根相对路径,跨源时前端拼 API origin) |
对象存储的其余后端(S3/OSS/COS/MinIO)配置落库在 SysStorageConfig,不写 appsettings。见 文件与存储。
XiHan:VirtualFileSystem
| 键 | 说明 |
|---|---|
IncludeCurrentDirectory / IncludeAppBaseDirectory | 是否挂载当前工作目录 / 应用基目录 |
XiHan:Workflow
工作流引擎,见 框架 · Workflow。要点:MaxNodeExecutionsPerBurst(默认 1000)、MaxSubWorkflowDepth(默认 16)、Worker:IsTimerEnabled(关掉后延时/重试/超时书签不会被自动恢复)。
Saas:Seed
注意这一节不在 XiHan: 命名空间下。
| 键 | 说明 |
|---|---|
EnableDemoData | 演示数据开关:true 才写演示租户与账号,缺省或 false 都不写,不是布尔值直接启动失败。开发环境配置开启,生产环境在 appsettings.Production.json 里设置 |
超管初始密码写在种子里(superadmin / SuperAdmin@123),不走配置;账号标记为需要本人改密,生产首次登录后立即修改,并建议在参数「密码设置」里开启强制改密。演示账号与各阶段种子见 框架简介:种子数据。
Saas:Conditions
条件求值用的设置,同样不在 XiHan: 命名空间下。
| 键 | 默认 | 说明 |
|---|---|---|
TimeZone | Asia/Shanghai | 时间类条件属性(environment.time、environment.hour、environment.weekday、environment.date)按这个时区计算,不带时区的日期时间条件值也按它解释。IANA 或 Windows 时区标识都认,本机找不到时启动失败。客户端带的 X-Timezone 请求头可以伪造,不参与条件 |
Saas:PermissionConditions
权限条件(权限模型 · 权限条件)的生效模式,改了热生效。
| 键 | 默认 | 说明 |
|---|---|---|
Mode | Enforce | Enforce:条件不满足即拒绝,返回 403「当前条件下不允许此操作」;LogOnly:照常求值但不拦截,本该拒绝的请求记进条件命中记录;Disabled:不求值,有条件的授予按授予、有条件的禁止按禁止处理,只作应急 |
Saas:AccessPolicy
访问策略的运行设置,改了热生效。
| 键 | 默认 | 说明 |
|---|---|---|
Enabled | true | 总开关。关掉时认证前、认证后、登录时的访问策略与自动封禁都不拦截,登录失败照常计数;用于误封自己后解围,见部署 · 误封了自己 |
VersionCheckSeconds | 5 | 每个节点最多隔多少秒检查一次策略是否改过,策略改动最多这么久后在所有节点生效 |
BanCheckCacheSeconds | 5 | 「这个 IP 没被封」在本机缓存的秒数,自动封禁最多这么久后在所有节点生效 |
HitBufferCapacity | 10000 | 命中记录在内存里按分钟合并时最多的合并键数,超出的命中只计数并告警 |
CodeGeneration
只在 appsettings.Development.json 里配置,appsettings.json 与生产配置都不放:不配置即不能生成到项目,只能生成并下载。
| 键 | 默认 | 开发环境配置 | 说明 |
|---|---|---|---|
EnableGenerateToProject | false | true | 是否允许「生成到项目」 |
BackendRootPath | — | ../.. | 后端源码根(相对 WebHost 项目目录),在其下分组目录里找与命名空间同名的项目 |
FrontendRootPath | — | ../../../../frontend | 前端工程根(相对 WebHost 项目目录),须含 package.json |
TablePrefixes | Sys_,Saas_ | Sys_,Saas_ | 由表名推导类名时去掉的前缀 |
生产不要开 EnableGenerateToProject
开启后代码生成器会往服务器上的源码目录写文件。位置虽由配置推导、不接受任意路径,生产环境也没有源码可写,保持关闭,用生成并下载。
数据库里的配置
有几类配置刻意不放 appsettings,而是落库以便按租户隔离与运行期热切换:
| 内容 | 表 | 页面 |
|---|---|---|
| 业务参数与功能开关 | SysConfig | /setting/config |
| 存储后端 | SysStorageConfig | /file/storage |
| 邮件 / 短信网关 | SysEmailConfig / SysSmsConfig | /setting/email-config、/setting/sms-config |
| 机器人 | SysBotConfig / SysTelegramBot | /setting/bot-config、/setting/telegram-bot |
| AI Provider / 提示词 | SysAiProvider / SysAiPrompt | /develop/ai-provider、/develop/ai-prompt |
它们通过 services.Replace(...) 覆盖框架默认的配置源实现。判断标准见 系统设置。
