Skip to content
bitzorcas
中EN

Guide

生产配置与启动守卫

为 API 与 JobHost 组织非敏感配置、Secret、Provider 选择、缓存预热、配置校验和滚动发布证据。

Last updated

生产配置的目标不是把开发 appsettings 填满,而是明确每个值的所有者、来源、变更方式和失败策略。静态默认值可以进仓库,Secret 进入 Secret Store,动态非敏感策略进入受控配置中心,基础设施连接由部署平台注入。

配置进入运行时

仓库默认值

Configuration

环境变量 / Secret Store

托管平台连接信息

AgileConfig 非敏感动态策略

启动校验与 Provider 选择

API

JobHost

Operations / Health 证据

配置归属

类别例子推荐来源
环境标识ASPNETCORE_ENVIRONMENT部署声明
Provider 与非敏感策略Persistence:Provider、限流窗口版本化配置/AgileConfig
数据库、Redis、RabbitMQConnection String、账号密码Secret Store 或托管连接注入
应用签名与厂商凭据JWT、SCIM、对象存储 Access KeySecret Store/KMS
遥测出口OTEL_EXPORTER_OTLP_ENDPOINT部署环境配置

环境变量使用双下划线表示层级,例如 ConnectionStrings__Default。不要把解析后的 Secret 写入 .env 并提交,也不要通过 AgileConfig 下发其自身的认证 Secret。

Terminal window
# ① 仅展示变量名和 Secret 引用;真实值由部署平台在运行时解析。
export ASPNETCORE_ENVIRONMENT=Production
export Persistence__Provider=SqlSugar
export ConnectionStrings__Default='<secret-store:sql-connection>'
export ConnectionStrings__redis='<secret-store:redis-connection>'
export RabbitMq__Password='<secret-store:rabbitmq-password>'
# ② 部署前构建同一 Release 制品,不在目标环境重新编译不同二进制。
dotnet build BitzOrcas.Modern.slnx --configuration Release --no-restore

启动守卫

生产启动至少验证:

  1. 必需连接、签名密钥和 Provider 已配置,长度与格式满足要求。
  2. API 与 JobHost 选择相同数据库、消息、缓存和数据保护语义。
  3. 关键 Port 解析到生产实现,而不是 InMemory*、Null* 或 Unavailable*。
  4. 文件、邮件、Webhook 等可选能力在未就绪时失败关闭,不产生假成功。
  5. Health Readiness 能反映必要依赖,但响应不回显连接串或 Secret。

动态配置并不适合所有键。数据库连接池、ORM Provider、密钥环位置和中间件组合通常需要重启;Feature、限流等策略可以热更新,但必须带版本、校验、审计与失败回退。

滚动发布检查

场景必须验证
新旧副本并存Schema、消息契约、Data Protection 密钥与缓存 Key 兼容
Secret 轮换重叠窗口、撤销旧值、失败回滚和审计
Provider 切换双 ORM 合同、数据一致性、迁移和回退计划
配置中心不可用启动/运行采用既定 fail-fast、fail-closed 或最后已知良值策略
JobHost 滞后API 写入不依赖未启动后台进程完成同步业务事务

发布证据还包括生产安全清单、GA 门禁和监控告警。

API 与 JobHost 的真实启动门禁

Production 与 Staging 都被视为类生产环境。API 缺数据库、RabbitMQ、Redis、OTLP、生产文件存储、Webhook 安全策略或正式 License 时抛 InvalidOperationException 并拒绝启动;Audit:StoreProvider=None 同样被拒绝。

JobHost 至少要求数据库、Redis、RabbitMQ、OTLP、审计存储与正式 License。数据库还承担 Quartz persistent store、Workflow store 与 Audit store,因此“只跑少数作业”也不能省略。

Terminal window
# ① 只设置变量名;值由 Secret Store 注入。TrustedPublicKeys 是数组配置。
export Licensing__Runtime__Enabled=true
export Licensing__Runtime__ProductId=BitzOrcas.Modern
export Licensing__Runtime__DeploymentIdentityPath=/var/lib/bitzorcas/deployment-id
export Licensing__Runtime__CachePath=/var/lib/bitzorcas/license-cache
export Licensing__Runtime__TrustedPublicKeys__0='<secret-store:license-public-key>'
# ② 类生产环境用实际制品启动;守卫失败必须阻断发布。
ASPNETCORE_ENVIRONMENT=Staging dotnet BitzOrcas.Api.dll

诊断输出只描述配置是否存在、长度或安全摘要,不应回显 Secret。门禁通过也不代表依赖可达,后续仍由 readiness 验证连通性。

Forwarded Headers 拓扑

API 位于反向代理后时,应显式配置 KnownProxies/KnownNetworks;若直接公网暴露,则使用受控的 ForwardedHeaders:DirectExposure 模式。错误配置会影响客户端 IP、HTTPS 判断、限流、审计归因,以及登录 Cookie 的 Origin 校验(依赖中间件回写后的 Host)。

在 Staging 用真实代理链验证 X-Forwarded-For、X-Forwarded-Proto、X-Forwarded-Host、X-Forwarded-Port 与 WebSocket Upgrade。OpenResty/Nginx 应把入口 Host 和 X-Forwarded-Host 设为 $http_host,以保留非默认端口;OpenResty → Gateway 两跳时 ForwardLimit 通常为 2。不要为了“先启动”而信任任意代理。

生产文档面的配置边界

非 Development 环境默认不映射 /openapi/v1.json 与 /scalar/v1。若内网预览确实需要文档面,同时配置 OpenApi__Enabled=true 与 OpenApi__RequireAuthentication=true:前者映射路由,后者要求正式账号换取 HttpOnly 文档会话。应用访问门只是一层纵深防御,入口仍应使用 HTTPS,并按环境风险叠加 VPN、IP 白名单或网关 SSO。

Terminal window
# 仅示意非敏感配置;公开入口由环境清单管理。
export OpenApi__Enabled=true
export OpenApi__RequireAuthentication=true
export OpenApi__Servers__0__Url=https://api-preview.example.com
export OpenApi__Servers__0__Description='受保护的预览网关'
export OpenApi__PersistAuthentication=false

Production 不需要交互文档时应保持关闭,并验证两个路由返回 404。共享预览应关闭 Scalar 认证持久化,避免调试令牌留在浏览器本地存储;文档访问会话本身是 HttpOnly Cookie,不写入页面脚本。配置中不得写入账号、密码、API Key、HMAC Secret 或 Token。Server 地址、登录路由和可信代理细节见 OpenAPI 与 Scalar 文档面。

缓存启动预热(Cache:Warmup)

业务读路径默认 Cache-Aside,不依赖启动预热。需要压低字典 / 多语言 / 设置等首包延迟时,可打开 Cache:Warmup(绑定 CacheWarmupOptions,默认关闭)。

键默认说明
Cache:Warmup:EnabledOnStartupfalse为 true 时 Host 启动后后台预热一次
Cache:Warmup:AreaKeys[]空 = 所有 SupportsWarmup 区域;建议显式列出
Cache:Warmup:TenantIds[]identity-* 等租户区域必须配置;空则只适合平台键区域
Cache:Warmup:StartupModeFillMissing启动仅建议补洞;全量重建走 Host API
Cache:Warmup:MaxDegreeOfParallelism2并行区域数
Cache:Warmup:AreaTimeout00:02:00单区域超时
Terminal window
# 环境变量示例:仅预热平台键区域,不扫全部租户。
export Cache__Warmup__EnabledOnStartup=true
export Cache__Warmup__AreaKeys__0=master-data
export Cache__Warmup__AreaKeys__1=translations
export Cache__Warmup__AreaKeys__2=settings
export Cache__Warmup__AreaKeys__3=delivery
export Cache__Warmup__StartupMode=FillMissing

运维侧也可在 Host 控制台对单区域执行 WARM / REBUILD(POST /api/operations/cache/rebuild),无需改配置重启。细节见缓存指南与 Operations 缓存治理。

配置变更流程

  1. 为键指定 owner、敏感级别、默认值、校验与重启语义。
  2. 在 Staging 使用与生产相同的注入方式,不粘贴 Secret。
  3. 运行启动门禁、readiness、配置诊断与核心 smoke。
  4. 轮换时保留最短必要重叠窗口,再撤销旧值。
  5. 保存配置版本与审批证据,不保存明文。

完成清单

  • API 与 JobHost 的配置矩阵分别验证;
  • Production/Staging 都无法落入 Shell、Null 或 None 实现;
  • License DeploymentId 与 cache 使用持久、受限路径;
  • OTLP、代理、对象存储和 Webhook 策略经过环境验收;
  • OpenAPI/Scalar 在生产关闭,或在外层保护后开启且不持久化认证状态;
  • Secret 轮换、配置中心不可用和旧副本并存均有回滚路径;
  • 若启用 Cache:Warmup:AreaKeys / TenantIds 已收口,并在 Staging 验证启动时延与数据库压力。

配置清单模板

每个环境维护不含值的配置清单:键名、Host、必需/可选、来源、Secret 标志、热更新/重启、Owner、最后验证日期。API 与 JobHost 共用键也要分别验证,避免只在一个 Host 注入。

对布尔开关记录缺失、false、true 三种语义;对 Provider 记录允许值与大小写;对数组记录索引/绑定方式。配置改名必须保留兼容窗口或提供迁移检查。

发布审查只比较清单与版本,不导出环境变量全量值。诊断工具发现未知、缺失或危险组合时应阻断,而不是自动猜测默认值。

  • 删除键前先证明所有副本不再读取;
  • Secret 版本与应用版本可以独立回滚;
  • 配置中心变更必须进入审计;
  • 紧急变更在事后补齐评审与演练。

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%