面向 Rust 服务端应用的受管生命周期与可靠业务执行框架。
nasa-runtime-rust 将配置校验、资源装配、业务初始化、接流许可和有序停机纳入同一应用生命周期,
并通过事务、Inbox/Outbox、Saga 与有序消息处理支持可恢复的业务流程。应用按 feature 选择能力,
使用已有的数据库和消息系统承载持久事实;各组件保留明确的资源、事务和失败边界。
受管长连接把监听、连接容量、首次认证期限和任务排空交给 naws,应用可使用内置消息模型,
也可接管原始 TCP/WebSocket 连接并定义自己的协议。动态 ProtocolBytes schema、共享接收预算和
独立资源指标支持配置驱动的连接服务;路由、订阅和业务授权仍由应用负责。
详见受管协议与资源边界。
SQLite 业务沿用 #[Mapper]、#[Query] 等 SQL 宏,由同一个 napp "db" 组件管理文件、迁移、事务和停机。
每个 datasources.<name>.driver 独立选择 MySQL、PostgreSQL 或 SQLite;详见 SQLite 文件数据源与统一 Mapper。
Kafka 能力提供与 Java nasa-kafka 对应的多数据源事件运行时:命名集群与 producer lane 隔离、有界有序消费、同集群原子处理,以及可持久接续的回放、转发和 DLT 回投。详见 Kafka 事件运行时。
通过具名连接同时使用 Nacos、Consul、Kubernetes 或 Static/DNS,按 qualifier 隔离内部调用,
并以完整 URL 访问互联网 API;连接与注册资源共用受管生命周期。
YAML 统一由 naml 提供有界读写,应用配置与 kubeconfig、Prometheus 等协议文档共用解析规则,
区分配置表达式求值与外部文档的字面值。见统一 YAML 入口。
配置装配支持嵌套默认值和自然排序的文件名导入,固定环境与来源权限后生成可解释候选;
来源观察和组件应用状态分开记录,错误候选保留当前可用视图。详见严格配置装配。
| 从哪里开始 | 中文 | English |
|---|---|---|
| 运行第一个 HTTP 服务 | 快速开始 | Quickstart |
| 理解资源、顺序和一致性边界 | 架构说明 | Architecture |
| 调整现有应用的依赖与接线 | 接入与升级 | Integration and upgrades |
| 参与组件维护 | 贡献指南 | Contributing |
业务唯一入口是门面包 nasa:业务项目只依赖 nasa,再按需开启 Saga、映射、事务、缓存、Redis、RedisJob、跨副本业务配额、WebSocket、配置、服务发现等特性。
其余成员用于实现和宏展开,默认不建议业务项目直接依赖。
Application 同时提供 Ready 前的业务初始化屏障和业务资源关闭前的有序异步收尾;业务不需要另建信号处理
或停机 callback 集合。
Redis 分区消费把持久接管与本地执行分开:不同 Redis 源始终使用独立 Runner,同源可按
source、group、stream 划分调度与容量;业务键顺序覆盖 handler、ACK 和精确重试。
可靠 Saga client 将业务事实与发起意图放在同一数据库事务,并让 dispatcher 固定扫描该事务域;
远端不可用或收据丢失时保留原事件,显式数据源冲突在 Ready 前拒绝。
Saga 已提交结果使用独立于 command 路由的恢复资格:参与方处于保护态或暂时没有 command route 时,
协调端仍可依据受信 Catalog、冻结定义与结果身份接收原事件,同时持续阻止新 Start、timer claim 和 Ready。
Mapper 同时提供默认采集的 SQL 指标,区分逻辑方法、真实数据库执行、连接等待和流消费;业务通过
同一份 YAML 配置开发 SQL/参数输出、慢操作与错误通知及指标出口,通知故障不影响业务事务。
慢 SQL 以原始耗时达到或超过配置阈值为准;业务安装 Notify、启用告警并关闭通知冷却后,每次命中
均尝试进入有界通知队列,发送协议与独立通知微服务由业务实现。
名称声明:本项目是独立开源项目,与美国国家航空航天局不存在隶属、赞助、认可或官方项目关系, 也不使用其徽章、标识、印章或其它官方视觉标识。完整声明见 NOTICE。
Application 标准纳管 Redis Stream/Proxy/AutoPipeline、出站 TCP 帧客户端、hystrix 命令目录、Mapper 缓存、命名幂等与审计、REST、对象存储、Schema Registry、 secret/TLS 与本地文件监听。业务提交配置与 handler,框架在接流前完成资源装配,统一管理健康、 配置应用状态和停机;无需为这些能力另建连接池、监听循环或关闭任务。各能力的入口和边界见 受管能力合同。 其中,Redis 消费、微批调用和出站 Client 与宿主终端共用启动许可,关键资源失效会阻止 Ready; 隔离命令由本代 Application 统一拥有,停机等待在途责任,旧句柄不能重新开放。
采用 Kafka 能力的现有应用需要完成公开 API 与默认配置迁移,详见迁移要求。
napp 管理应用启动与关闭,naws 管理监听和连接任务,naws-proto 管理受限编解码,
nafka/nadis 提供外部消息来源,nafana 提供独立观测。各层共用生命周期,但不互相代替授权或持久确认。
Application 启动许可 → naws 监听与连接容量 → 应用协议处理器
├─ 身份与路由授权 → 业务动作
├─ ProtocolBytes schema → 有界正文
└─ 登记读写子任务 → 关闭与实际退出屏障
原始消息来源 → 保留正文及处理责任 → 当前权限复验 → 交付 / 持久确认
固定指标目录 → Ready 前预留序列 → 独立指标出口与平台查询
自定义协议处理器接收原始连接与 ProtocolContext,不自动执行内置 endpoint、bridge 或 relay。
认证沿用 accept 时确定的截止点,完成通知不延长业务身份寿命;服务停止后,迟到确认不能重新接流。
共享接收预算随真实缓冲和最后一个正文 owner 释放,取消观察者不取消仍在执行的工作。
动态 schema 可配置字段、集合和嵌套对象,但不能加载任意代码,也不能定义业务权限。
socket-center 使用这些通用能力实现自己的路由、授权、订阅与控制权威;这些产品合同不进入基础框架。 指标样本缺失、过期或不支持分别表达,图例保留查询输出的区分维度;抓取成功不证明业务来源有权写入。 完整接线、配置和失败边界见协议宿主、naws、 动态 schema和资源观测。
启用 kafka 后,业务统一使用 nasa::kafka;结合 application 和 "kafka" 组件,单源配置使用 kafka,多源使用 kafkas.<name>,两根互斥。app.kafka(name) 返回绑定来源的业务句柄,显式未知名称不会回退。Java/Rust 共享事件线路、组名、稳定事务身份和有限任务持久格式;API 和配置拼写遵循各自语言。
命名配置 → 单源 KafkaProxy → 独立 producer lane → broker 交付确认
├─ 多 owner 消费 → 有界路由执行 → 当前代次安全前缀 → 提交
├─ 专属事务 → 完整输入位点 + 批准输出 → 原子 commit
└─ 有限任务 → 处理或目标确认 → checkpoint → 进度发布
普通消费支持分区顺序与按键并发,输入责任由进程、源、组、分区和 key 共同限制;旧 Ack 失权不能推进新 owner 的位点。独立 lane 隔离发送额度,不隔离整个进程的 CPU、内存或 broker。fire 受理、broker 交付和事务 commit 是不同确认时刻,取消等待不抹掉在途责任。
同集群事务使用稳定部署身份与专属资源,将完整输入位点和批准输出原子提交;提交未知时保护 owner 并按原身份恢复。有限 Replay、单目标 Transfer 与 DLT 回投先确认处理或目标,再持久推进进度,允许重复而不伪装为跨资源原子事务。数据库、HTTP、socket 和其它 Kafka 集群的副作用不自动进入事务。
业务通过当前 Ready、组及单槽健康、交付状态、64项固定指标目录和关闭报告观察实际责任。Admin 默认只读,写权限须按源显式开放并满足 broker ACL。合法组名原文不变,非法组在业务开放前拒绝;事务还要求 broker 内部 listener 可达及事务日志满足副本和 ISR 条件。
完整架构与能力边界 · 受管配置和生命周期 · 属性宏声明 · 部署前置条件
任意 Rust 微服务都可以使用 nadisc-runtime 管理多个独立注册中心,不依赖 Saga 或数据库。具名连接隔离凭据、服务作用域、发现证据和故障;显式注册清单决定当前服务发布到哪些环境。Static/DNS 为地址来源,Nacos、Consul 和 Kubernetes 分别保留各自健康与权限边界。
独立宿主持有唯一 DiscoveryOwner;使用 napp 时由 #[nasa::application("web", "discovery")] 接管 prepare、启动确认、资格探针、注册摘流、业务排空和最终关闭。启用 discovery-runtime,按需增加 discovery-nacos、discovery-consul、discovery-kubernetes;REST 请求构建器使用 rest-discovery,声明式 Mapping 使用 rest-client,动态 gRPC 使用 grpc-discovery。旧 nacos-discovery 入口仍可使用,新旧配置根节点不能同时声明。
旧单 Nacos 接口使用派生组件 nanacos-sdk 维护兼容传输;控制流丢失即撤销连接健康,再由既有 SDK 状态机重连。新 owner 的 HTTP adapter 独立工作,不叠加 SDK 注册监督。
app.discovery()?.client(Some("business")) 选择发现环境;rest(Some("business")) 返回该环境的共享 HTTP 客户端,默认 REST 门面使用 primary;兼容配置的显式默认引用优先。生成的 gRPC 客户端可注入受管 DiscoveryGrpcService。完整空集、权限撤销、期限耗尽与关闭会拒绝新提交;已经提交的请求仍须按业务幂等与结果不明语义处理。
选择注册中心统一使用 qualifier,默认连接命名为 primary,无需额外默认配置字段。五种 REST Mapping 都支持 qualifier = "business";方法级值覆盖 trait 默认,通过 Client::with_clients(app.discovery()?.rest_clients()?) 注入共享集合。未指定时选 primary,缺少 primary 或显式名称不存在时不会猜选其他环境;旧单客户端注入继续可用。
#[GetMapping(url = "https://dns.google/resolve")] 使用默认 HTTP 客户端访问公网,不查询 Nacos。
url 模式不能配置或继承 qualifier;宏不读取 YML 占位符。完整配置、内部服务及 Google API
示例见调用指南。
多个注册目标分别设置可达 IP 与映射端口,不能把容器监听地址当成宿主地址。Saga 可另外选择基础设施连接,并为续租与已提交结果设置独立恢复目标;恢复资格不授予新业务的目录执行权。
完整配置、架构、手动接入与停机合同 · Consul · Kubernetes
项目围绕三个相互配合的能力组织:统一的应用生命周期、可恢复的事务与业务流程、受容量和顺序约束的 消息执行。适合需要组合数据库、消息系统与服务入口的 Rust 后端;只需要单项能力时也可显式装配组件。 应用层资源管理建立在 Tokio 和所选基础设施之上。项目不提供新的异步执行器、数据库或消息 broker。
nasa 把配置收敛、依赖校验、组件启动、Ready 发布和反向停机统一为一个受管生命周期,让业务只选择
需要的能力,同时保留各基础设施组件的真实事务、租约和故障边界。核心价值是让配置错误、资源缺失和
安全门禁在开放流量前失败,并让运行中的权威变化、队列背压和停机排空保持可观测、可控。
Service 的受管主流程如下;Batch 在工作负载前装配并开放所选出站资源与观测任务,不发布 Service Ready:
本地配置 + 远端配置
│
v
最终 YAML → 全量校验与资源探测 → initializer 初始化 → Ready 装配与任务工厂构造
│
静态检查、关键资源与共享启动预算复验
│
本地状态保护内提交 Ready 与统一启动许可
│
受管终端、Redis 消费与出站入口获准运行
停机信号 ──→ 关闭业务入口 ──→ 停止新后台动作 ──→ 反向排空 ──→ 释放资源
Application 不提供跨数据库原子事务,也不会替业务推断租户身份、授权关系、消息投递闭环或生产容量。
独立组件可以脱离 Application 显式装配;此时连接、启动门禁、停机顺序和可观测性由调用方负责。
端口绑定不代表已经接流;受管 gRPC 在 Bound 阶段不处理 RPC。服务发现只在统一放行后注册,
注册确认前 app.is_ready() 与 /readyz 仍不可用,不能只凭生命周期状态或 TCP connect 判断就绪。
统一放行约束组件交出的终端任务与 initializer 暂存任务,不延迟 UserHook 中普通
spawn_background / spawn_critical。业务自管 listener 使用 serve_when_ready;initializer 的任务
工厂应只构造 future,不自行启动监听或派生任务。
| 能力 | 门面 feature 与配置 | 使用与关闭边界 |
|---|---|---|
| 普通 Stream 与 Proxy | application,redis,声明 "redis";redis_streams、redis_proxies |
Service 登记 handler,统一放行后消费;排干与 Proxy PEL 清理共用停机期限 |
| AutoPipeline | application,redis,声明 "redis";redis_pipelines |
Service 与 Batch 的命名微批;有界参数字节,未知写入结果不自动重放 |
| 原生 TCP Client | application,ws-client;ws_clients |
不需入站 listener;Service 可登记回调,Batch 可发送;入队不证明远端送达 |
| hystrix 命令目录 | application,hystrix;hystrix.enabled: true |
固定规则、命名命令、属性命令共用本代 owner;业务收尾后排干并撤销目录 |
关键 owner 的任务责任、Client 的认证连接和健康证据在 Ready 发布前复验,本地状态保护持续到
启动许可发布完成。该顺序保证公开 Ready 时入口已获许可,不保证未被本地观察到的远端故障不会发生。
运行期关键 Client 断连使动态 readiness 为 NotReady,重新认证后恢复;可选 Client 断连为 Degraded。
配置和认证材料冻结到启动,变化报告 RestartRequired。这些能力不提供跨系统原子事务、远端送达
保证或错误率熔断状态机。完整配置、容量和观测入口见 napp。
feature 决定编译期能力,组件声明决定连接与任务的生命周期,命名计划以 enabled: true 显式启用。
Service 在 UserHook 登记计划,标准命名资源在 Prepare 装配,供 initializer 和 Ready 后的业务使用;
Batch 在工作负载前完成装配。名称、来源和容量在启动时校验,显式错源不会回退到默认实例。
最终配置 → 来源连接与迁移门禁 → 命名资源装配 → initializer → Ready 后业务
配置变化 → 材料与资源候选准备 → 复验当前视图 → 发布配置与实际应用状态
停机 → 撤销新调用与任务准入 → 等待在途工作退出 → 释放所属资源
本地文件与 Nacos 更新共用候选流程。secret、TLS 和日志先在发布锁外准备;候选失败保留旧视图。
已支持的日志与命名 TLS HTTP 参数可热应用;连接来源、对象存储和 Schema Registry 的参数或凭据
变更要求重启,状态报告 RestartRequired。读到新配置不代表所有组件已经采用新参数,业务应固定
一次 config_view() 并查看实际应用状态。文件观察只覆盖活跃消费者所需材料。
资源句柄不授予第二份关闭权:停机后旧受管句柄拒绝新调用,已接纳的工作仍须归还责任。 对象存储按显式策略监督健康;Schema Registry 构造不证明远端可用。诊断快照只组合已有证据, 不主动探测后端,也不是跨组件的原子快照。事务原子性、租约 fencing 和写入结果未知仍由各组件 合同约束,取消等待不能证明远端未执行。
Application 通过 configure_redis_partition 接收逐来源消费计划,统一负责 Ready、健康和聚合停机。
业务从 redis_partition(source) 获取受管句柄,无需另写消费循环或停机 callback。
nasa::redis::PreparedPartition 先准备物理 Stream 并冻结消费计划,start 返回拥有消费生命周期的
RunningPartition。Redis 租约、PEL 和 fencing 决定跨进程接管权;实例专属的 napart Runner 集合
负责本地调度。读取前预留记录、正文和后继责任,handler 成功后由提交监督完成 ACK;ACK 结果
不确定只进行对账,不重跑已成功的 handler。
Redis 来源租约与 PEL → 有界读取 → 共享账本与业务键顺序门禁
↓
来源所属 napart Runner
↓
业务结果 → ACK 或精确重试
redis.partition.executor.scope |
本源实例的执行归属 | 适用场景 |
|---|---|---|
source(默认) |
全部组和物理 Stream 共用一个 Runner | 统一调度,使用完整源级预算 |
group |
每个默认组或隔离组独立 Runner | 按业务组隔离慢任务和积压 |
stream |
每个 (逻辑组, 物理分区编号) 独立 Runner |
同组内各物理 Stream 也需要独立推进 |
不同 Redis 源不共享注册表、容量或停机控制。group、stream 的域表按完整配置拓扑冻结,
记录、正文、读取批次和待删 ID 在源级总额内分为固定、不借出的份额;预算不足以覆盖每域一批读取
时拒绝启动。Redis 物理分区数由 partition.count 和组覆盖决定,本地槽数由
partition.executor.partitions 决定,两者含义不同。
同一实例、同一消费计划、同一业务键仍跨域保序,不能通过拆 Runner 绕过 ACK、重试或 Park。 需要跨进程同 key 串行时,生产者须把规范化业务键路由到同一物理 Stream;交付仍为至少一次, 业务必须幂等。各域共享 Tokio runtime 和 Redis 客户端,执行隔离不等于线程、连接或后端服务隔离。
这些 Runner 由消费器拥有,与 Application 的 partition.runners 分属不同生命周期。
snapshot().execution_domains 提供各域容量和运行状态;正常停机须检查
shutdown_until(deadline) 的 converged,超时可继续等待同一排干操作。
接入、容量计算与故障边界见 nadis 和
分区消费说明,调度内核见 napart 运行架构。
application + mapper、application + mapper-pgsql 或 application + mapper-sqlite 自动把方法指标、连接与 Pool 指标、有界通知
和统一指标出口纳入运行时,不需要业务实现 Mapper Hook、周期采集任务或 metrics Router。
所有可调策略支持 YAML,非必要项递归提供默认值,未知字段、目录外引用和越界配置在启动时拒绝。
sql.observability 控制逐条 SQL、开发参数、慢日志、错误日志、等待阈值与通知;基础指标始终采集。
业务实现 Notify 并通过 nasa::application::notifications::init 主动安装,未安装时忽略通知;
默认不需要 notifications.providers 或 provider_ref。多命名渠道可选,通知微服务的调用协议由业务
决定,框架不内置消息渠道客户端。
grafana.observability 控制独立/Web 抓取、remote write、身份与平台期望资源。应用只持有数据面所需
凭据,平台资源由独立 controller 调和,不从业务副本调用 Grafana 或 Kubernetes 写 API。
remote write 失联规则只引用外部平台持续提供的期望实例指标,不维护实例清单,也不把应用心跳当成
“本应在线”的依据。
以下配置以 1000 ms 为慢 SQL 阈值,并关闭重复通知冷却;业务还须在启动前或初始化阶段安装 Notify:
sql:
observability:
slow_sql:
threshold_ms: 1000
alerts:
slow_sql:
enabled: true
cooldown_ms: 0关闭慢日志不关闭通知;阈值不包含连接等待、缓存处理或 Stream 消费者处理时间。默认通知冷却为
60000 ms,需要逐条通知时必须显式设为 0。同次执行既慢又失败且已启用错误通知路由时,优先按错误
规则发送并保留 slow 事实,不重复发送两类事件。
逐条 SQL 与参数默认关闭;参数仅允许显式开发环境、强制敏感名字脱敏并限制数量和长度。 通知投递不持久化、不提供跨副本去重,队列满、超时与渠道失败均不改变 SQL 结果、事务裁决或数据库 readiness。集群失败率与分位数告警由监控后端聚合。 完整字段与默认值见 SQL 观测, 出口与平台边界见 nafana,通知扩展合同见 nanotify-core。
Service 与 Batch 都可在 UserHook 调用 app.register_graceful_shutdown(priority, name, future),
登记一次性的 close、flush、归还或注销。成功登记即移交 future 所有权;UserHook 结束后不再接收任务。
两种模式都先收口受监督任务,再执行业务停机任务,随后释放 UserHook 登记的业务资源。
Service 在业务任务前完成入口摘流、Ready action 与 initializer 清理;Batch 在工作负载之前初始化,
因此在业务任务和业务资源之后才撤销静态 initializer,最后释放更早启动的组件资源。
任务可以执行时再查找尚未清理的资源,不必提前长期占用借用。
| 业务需求 | 入口 | 所有权与边界 |
|---|---|---|
| Ready 前初始化 | #[nasa::initializer] / register_initializer |
migration 后执行全局屏障,失败不接流 |
| 一次性异步收尾 | register_graceful_shutdown |
在任务组内按 priority 升序、同优先级按登记顺序执行 |
| 资源本体的关闭 | register_managed |
由资源所属的生命周期步骤关闭,同一对象只保留一个关闭 owner |
任务共享 application.shutdown_timeout_ms 的绝对期限,组内公平分配剩余预算并为后续清理预留时间。
单项错误、超时或可隔离的展开不覆盖首次终止原因;有剩余预算时继续后续项,未开始项计为 Abandoned。
直接取消 Runner 会同步撤销本实例的全局入口和新资源借用,将 Starting/Ready 置为 Stopping,
已有 Stopped/Failed 保持不变。已借出的资源随借用归还释放,此前复制的外部客户端句柄不在撤销范围内。
已激活 action、停机任务与所属资源按实际激活栈逆序同步释放,保持 Service/Batch 各自的 initializer 位置。
经过任务门时,仍存活的受监督 future 接管后续释放责任,最后一个 future 析构后才释放清理尾部;
取消调用方不等待这一过程,全局入口和新借用立即撤销。任务不让出执行权时,依赖也必须继续保留。
直接取消不保证执行异步收尾或生成退出报告,Stopping 也不表示异步清理完成。
同步阻塞、非协作 poll、panic=abort 和析构自身展开期间的未隔离再次 panic 不受异步期限保护。
名称、容量、资源借用、析构隔离和诊断计数的完整合同见 napp 业务优雅停机任务;运行期判断见 运维指南。
Application 可从最终 YAML 同时创建多组 MySQL、PostgreSQL、SQLite、Redis 与 Kafka 连接,并把它们冻结为当前进程唯一的 命名资源表。业务通过 qualifier 取得句柄;Inbox、Outbox、幂等、审计与 Saga 等持久适配器也把 datasource 身份固化在自身句柄中,不需要各自维护连接池或依赖隐式默认库。
最终 YAML → 全表校验与逐源探测 → 冻结命名 registry → Ready
│
├─ Application getter
└─ 事务 / Mapper / 持久适配器
停机信号 ← 撤销 registry 发布 ← 停止新事务并按生命周期反向排空
datasources:
default:
driver: mysql
url: ${APP_PRIMARY_DB_URL}
workflow:
driver: postgresql
url: ${APP_WORKFLOW_POSTGRES_URL}
outbox:
datasource_ref: workflow
saga:
role: orchestrator
plan_mode: managed
service_identity: checkout-orchestrator
replica_identity: ${SAGA_REPLICA_ID}
database_bootstrap: application
orchestrator:
datasource_ref: workflow
definition_catalog:
mode: dynamic
datasource_ref: workflow
activation_policy: validated
watch_interval_ms: 500
capability_registry_ref: saga-participant-capabilities
publisher_authorization_policy_ref: saga-definition-publishers
api:
page_token_key_ref: saga-api-page-token
http:
enabled: true
authorization_policy_ref: checkout-saga-http-rbac
callers:
order-api:
credential_ref: saga-order-client
tenants: [system]
permissions: [start, read]
transport:
address_policies:
saga-participant-routing:
http_schemes: [https]
http_hosts: [inventory.internal, payment.internal]
http_ports: [443]
command_result:
kind: http
http:
shared_replay_claim: saga-http-replay
command_credential_ref: saga-command
result_credential_ref: saga-result
routing:
mode: capability-registry
address_policy_ref: saga-participant-routing
redis:
properties:
primary:
url: ${APP_PRIMARY_REDIS_URL}
namespace: orders
profile: RustV2
sessions:
url: ${APP_SESSION_REDIS_URL}
namespace: sessions
profile: RustV2任一 source 无效都会在 Ready 前拒绝整张表;显式引用未知名称时不会猜测唯一实例,也不会回退到
default。同一原子链中的业务写、Inbox、Outbox、审计与 Saga 必须绑定同一 datasource。本能力不提供
跨数据库原子事务,也不热切换 endpoint、凭据或 source 集合;这些身份变化需要重启并重新完成启动
门禁。完整配置、查询入口、失败语义和停机边界见
napp 的单源与多源章节。
Inbox 去重标记的删除必须晚于消息源最大重投视界。业务显式提交 InboxRetentionPlan 后,Application
在 Ready 后以串行 fixed-delay 循环治理到龄标记,并公开删除、owner 争用、预算耗尽、失败轮次和最老
候选年龄的无标签指标;它不会猜测 Kafka 或其它消息源的保留策略,也不会在线创建生产索引。停机时
先停止新轮次,再收口当前数据库动作;锁状态未知的连接不会返回连接池。配置和非目标见
napp Inbox 章节。
Web 安全边界把 route 策略、未命中缺省和 generation 作为一次原子发布的完整授权快照。请求进入后
冻结该快照,Web 中间件、PolicyRegistry 便捷入口和 handler 内的 RequestSecurityContext 使用
同一裁决语义;显式 route 策略始终优先,公开路由或健康探针豁免只能作用于没有显式策略的 route。
permit、observe、deny 三态缺省用于逐步收紧覆盖面,对象授权缺失、拒绝、错误或超时均
fail-closed。认证仍由 OAuth/JWKS 或业务身份层负责,授权层不验签 token,也不推断租户或对象归属。
已验证 Principal + 稳定 route ID
│
v
PolicySet + UnmatchedRoutePolicy + generation ──→ route 裁决
│ └─→ 同请求对象授权快照
└─ 校验成功后原子发布;失败保留 last-good
链路传播严格遵守 W3C traceparent flags:合法上游上下文原样继承 sampled 位;缺失或非法上下文只有
在 exporter 存在时才由冻结的 root_sample_ratio 裁决新根,纯传播入口始终创建未采样根。REST 与
Kafka 出站复用请求上下文。调度器仅在 leader gate 和 FireLog claim 都通过后创建执行 span,并记录
稳定任务名与名义触发时刻;未取得执行权的拍次不会伪装成已执行。完整配置、指标与失败边界见
naauthz、natelemetry 和
nasched 调度 trace。
rate-limit feature 提供 RateLimitProvider 和共享 Redis 固定窗口实现,让所有副本对同一 tenant、
subject、API key 或客户端 IP 合并计数,扩容不会成倍放大业务总配额。业务从 Application 取得受管
Redis 客户端后显式构造 provider,并选择直接判定业务主体或安装 Web 中间件;中间件可从已验证
Principal 选择 tenant、subject/client_id,也可选择真实客户端 IP 或摘要后的 API key。它没有组件
字符串和独立 YAML 根,也不会自动改变路由。
Redis Lua 在服务端原子完成计数与首次过期设置。默认 Redis provider 在后端不可达、窗口非法或脚本 失败时默认 fail-open 并记录告警,优先保持业务可用;高保障入口可把 Redis provider 配置为 fail-closed。该能力与 Web 的单实例令牌桶分层:前者约束跨副本总量,后者只保护当前进程。
application + mapper-sqlite 让同一个 "db" 组件管理 SQLite 文件 owner、连接、迁移、观测与停机。业务从 nasa::mapper::sqlite 导入 Mapper,继续以 #[Mapper]、#[Query]、#[Insert] 等宏操作 SQL。每个 datasources.<name>.driver 独立选择 MySQL、PostgreSQL 或 SQLite;编译时启用实际使用的后端,SQLite 独立组合不引入其它数据库 runtime。
Cargo 后端能力 + datasources.<name>.driver
→ napp 全表校验与逐源打开 → 文件 owner / typed registry / 统一 catalog
→ 显式迁移计划与 Prepare 门禁 → 业务初始化与开放
→ Mapper 绑定与映射 → 受控 executor → 同源原生连接与事务
→ 停机封口、限时排空 → 原生关闭确认 → 释放容量与文件权威
配置选择资源的 driver,宏导入路径确定 SQLx 类型,二者必须一致。SQLite 用 sqlite.path,MySQL/PostgreSQL 用 url;数据库组件字符串始终为 "db"。迁移策略不包含 SQL 计划:Service 在 UserHook 登记,Batch 使用 MIGRATION_PLANS,门禁失败不执行工作负载。完整可运行示例见 SQLite 接入指南。
请求预算在独立租约接纳前与配置上限取较短期限,覆盖取连接、首次 SQL 前的持有和结果消费;取消等待不会提前释放真实原生责任。环境事务保留独立总期限,提交确认后才运行有界 after_commit。统一观测区分方法、执行、连接等待、物理连接、WAL/空间压力和持续隔离。
SQLite 使用 sqlite.path,已有文件不隐式切换日志模式;支持同源事务、只读连接、受控流、原生一致备份与恢复到新目标。仅支持 Linux/macOS 本地私有文件,不提供 SQLite Saga/Inbox/Outbox 或跨库原子事务。详见 受管配置与混配、事务与文件权威、Mapper 和 迁移。
开启 application 与 PostgreSQL 对应 feature 后,#[nasa::application("db")] 会从 database 或
datasources 建立 PostgreSQL pool;同一 datasources 表可以同时声明 MySQL 与 PostgreSQL。跨 driver
名称空间由一个 catalog 冻结,业务分别使用 app.datasource(name) 与 app.pg_datasource(name) 取得
typed pool。任一 datasource 建池、迁移或引用校验失败都会阻止整张表进入 Ready。
不使用 Application 生命周期时,PostgreSQL 应用也可以直接组合命名事务、migration、Mapper 与
持久 adapter。natx-pgsql 提供 default/命名 datasource registry 和 ambient transaction;
namigrate-pgsql、namapper-pgsql 分别承载 schema 门禁与 SQL 映射;naidempotency-pgsql、
nainbox-pgsql、naoutbox-pgsql 与 naaudit-pgsql 复用同一 datasource,不各自创建连接池。
PgPool registry ── natx-pgsql ambient transaction
├────────── migration / Mapper
└────────── idempotency / Inbox / Outbox / audit
事务内跨 datasource 调用会在 SQL 前拒绝。跨数据库副作用不属于本地原子事务:需要源库 Outbox、目标库
Inbox 和稳定 event_id 收敛至少一次投递。PostgreSQL Outbox 以数据库 owner 租约和 fencing token
限制投递权威,通过 FOR UPDATE SKIP LOCKED 领取稳定 id 前缀;只有明确成功前缀可以标记完成。
受管 Outbox 与 Saga 根据 datasource_ref 的 driver 选择对应持久后端;二者形成同一原子链时必须指向
同一个 datasource。full-pgsql 提供 PostgreSQL-only 的完整门面组合,不拉入 MySQL SQLx runtime;
同时开启 full 与 full-pgsql 则允许两种 driver 在同一 Application 中共存。
YAML 中的 migrations 只定义门禁策略;Service 仍需在 UserHook 用
app.configure_migrations(datasource, sqlx::migrate!("./migrations")) 登记构建期嵌入的业务 SQL。
门禁模式不是 disabled 时,PostgreSQL 事务级代理还需提供与业务池指向同一 database/schema 的
migrations.session_url;Application
会在 advisory lock 前复验目标身份。完整入口与 Batch 边界见
napp 的业务 migration 登记章节。
声明 Saga 组件后,Application 根据受信配置中的 saga.role 构造互斥运行角色。orchestrator 拥有全局实例、 journal、timer、result Inbox 与 command Outbox;participant 只拥有本地 command Inbox、gate、业务事实 与 result Outbox;client 只获得远程 start/query 能力,启用 reliable_start 时才创建本地 start-intent Outbox。业务 main 不构造 DefinitionRegistry、Orchestrator、SagaApplicationPlan 或 dispatcher。
MySQL 与 PostgreSQL 的受管步骤工厂分别登记,可以同时编入一个程序;每个步骤仍绑定自身后端与事务域。 MySQL 租户配额在创建和终态事务内维护,对账使用当前锁定读;事实行有锁冲突时拒绝覆盖账本, 调用方须回滚整个事务后有界重试。阶段耗时为全部固定阶段预留完整直方图容量,未采样阶段保留零计数。
managed 数据面支持 HTTP、gRPC、Kafka 与 Redis Streams。Application 按角色自动构造 publisher、
consumer、Inbox/Outbox、DLT、健康门禁与停机排空;HTTP 和 gRPC 还提供标准 start、get、query、audit、
管理、Definition Registry 与 metrics API。参与方从已链接的 #[saga] descriptor 构造 handler,并通过
独立 Registry 控制面自动续租 capability;HTTP descriptor 发布逐实例 effective_saga_base_path,其它
数据面发布各自的 topic、stream 或 mTLS endpoint。route generation 由 Catalog 数据库在 capability
主键行锁内单调分配并随登记收据回传,不使用参与方墙上时钟。流程所有者通过
#[nasa::saga_workflow] 提供完整、
有序且不可变的 definition,napp 使用独立 Ed25519 私钥形成 seal 并自动发布,Orchestrator YML 不枚举
workflow、step 或 participant owner。
workflow owner ── definition seal ──→ 持久 Definition Catalog
participant ── capability lease ────→ owner/实例/path 路由
│
client start-intent Outbox ──→ Orchestrator DB ── command Outbox
│ │
└─ result ← participant 本地事务
command capability 决定新业务能否路由,result 资格只决定已经由参与方本地事务提交的原结果能否继续 收敛。动态 Catalog 必须覆盖全部在途实例的冻结定义,结果 producer 信任仍须有效,目录中的租户、 workflow、定义版本和摘要集合必须与已发布 registry 一致;缺少 command route 或健康探测失败不会单独 阻断结果,但也不会开放新 Start、管理操作、timer claim 或 Application Ready。
每个结果请求冻结证据期限、撤销身份、安全配置发布代际和合同摘要。HTTP 的异步认证以及 HTTP/gRPC/Kafka/Redis Streams 共用的状态事务持续复验同一资格;等待连接池或实例行锁不能借后来续期 延长原请求。安全材料经历 A→B→A 后,单调发布代际保证旧资格仍然无效。失权时整笔结果事务回滚, 原事件保持可重投且不消耗普通隔离预算;COMMIT 已经发出后仍由数据库收据或提交结果不明语义裁决。
每次本地事务明确提交后,只发送按 driver、datasource_ref 与 lane 限定的轻量唤醒;统一 dispatcher 仍按数据库中的最早持久前缀、claim、退避和收据规则投递,周期扫描只承担漏信号、跨进程写入和崩溃 恢复。HTTP/gRPC 只有 Committed 或 Duplicate 允许 Outbox 前移,Kafka 需要 broker ACK,Redis Streams 需要 XADD 收据;任何网络结果不明都保留原事件。
nasaga-runtime-core 同时发布内部 saga_transport.proto 与业务 API saga_orchestrator.proto,并导出 generated Rust 模块。capability/definition Registry 协议与 command/result 数据面彼此独立,因此 Kafka 或 Redis Streams 数据面也可以选 HTTP 或 gRPC 作为控制面。Saga 不提供跨服务 ACID、物理 exactly-once 或并发业务隔离。 业务资源竞争仍需唯一键、条件更新或语义锁。配置与失败边界见 napp Saga 受管模式, 状态机与恢复语义见 Saga 生产运行指南。
启用 saga.client.reliable_start 后,业务在 saga.client.datasource_ref 对应事务中写入业务事实,
再调用 SagaRemoteClient::enqueue_start 追加 start-intent。方法返回稳定 event_id 只表示事务内
追加成功;必须等外层事务明确提交后才能向调用方表示本地已受理,不能据此宣称远端 Saga 已创建。
client 指定数据库:业务事实 + start-intent ── 同一事务提交
│
v
同源 dispatcher ──→ 远端 Orchestrator
└─ 结果不明:保留原 event_id 重投
dispatcher 不继承全局 Outbox 默认数据源。显式 outbox.datasource_ref 必须等于
saga.client.datasource_ref,即使两个数据库都已建表也不能混用;冲突时配置校验给出这两个键的诊断,
不进入 Ready。省略 Outbox 段或只设置轮询预算不改变绑定,MySQL 与 PostgreSQL 规则相同。
只有远端返回 Committed 或 Duplicate 才确认事件已投递;Ready 与 HTTP 已受理响应都不代表流程
完成,积压需结合 napp_outbox_pending、发布量和远端实例状态判断。
Kafka Schema Registry、对象存储、gRPC listener 和受管 Web listener 已形成稳定公共合同,并继续用
独立 feature 控制依赖面;full 会显式纳入这些能力。它们都定义容量与超时上限、唯一所有权、
敏感信息脱敏、失败语义和可观测事实。
| 能力 | 解决的问题 | 运行架构 | 明确不负责 |
|---|---|---|---|
| Schema Registry | Confluent envelope、批准 ID、有界查询/等待/缓存、独立 CA/mTLS、取消后的请求责任 | 独立 client,或 Application 按 schema_registries.<name> 装配的命名资源;无需声明 Kafka 消费组件 |
codec 生成、引用解析、schema 治理、subject ACL、灾备复制 |
| 对象存储 | 有界单对象读写、条件创建、SigV4 与内容完整性 | provider-neutral trait + path-style S3 adapter;可独立构造,或由 Application 按 object_stores.<name> 托管 |
multipart、流式/range/list、STS 刷新、对象版本治理 |
| gRPC | 统一 codegen、generated service registry、可配置消息/请求上界、HTTP/2/TLS/方法门禁、具名发现调用、观测与有预算排空 | 独立 handle,或交给 Application 的 listener 与 discovery owner 托管 | proto 业务语义、service mesh、业务授权 |
| Web listener | 确定的 HTTP/1/h2c 选择、连接与 stream 上界、协议观测和有预算排空 | Application "web" 组件独占明文 TCP listener 与路由服务图 |
TLS 终止、h2c Upgrade 协商、服务间协议选择 |
独立模式由业务显式构造 ConfluentSchemaRegistry 或 S3ObjectStore 并持有实例。受管模式分别开启
application,kafka-schema-registry 或 application,object-store,在对应命名配置中设置 enabled: true,
无需新增组件字符串。Application 在 Prepare 使用同代配置与 secret:// 材料装配资源,业务通过
app.schema_registry(name).await 或 app.object_store(name).await 取得句柄;Service 在装配后的
initializer 或 Ready 后任务中使用,Batch 在工作负载开始前完成装配,无需启动 Web 或 Kafka 消费者。
未声明或禁用的计划不建立客户端、不读取其独占凭据。受管路径自动登记聚合指标、关闭新调用并等待在途调用,
停机后旧句柄返回 Closed;不要为同一受管资源再次手工登记指标。配置或凭据变化报告 RestartRequired。
对象存储按显式健康策略探测并影响 readiness;Registry 构造不探测远端、不注册 schema,也不证明远端健康。
配置与生命周期边界见 受管能力合同。
gRPC 受管模式由容器独占 shutdown,在 initializer 全部完成前不会绑定端口。Web listener 只有在同时启用 application,web
feature 并声明 #[nasa::application("web")] 时才由容器创建;满足这些前提后,最终 YAML 的
server.http2.enabled 决定是否接受 h2c。各组件 README 是默认值、观测判读和成熟度边界的完整合同。
启用 redis-job 后,运行时按“计划冻结 → 能力快照 → 调度投递 → receipt/租约 → Handler 执行 → CAS 对账”的路径工作。Fanout 在目标节点持久确认接收后再申请本地执行槽。槽位不足时使用有界容量窗口和独立容量路由预算:超窗优先切换兼容执行器,无候选时继续保留当前 assignment,不把健康满载节点判为失联。shard 的 capacityRouteTotal 持久记录历史容量迁移次数,capacityRouteCount 只表示当前路由预算;实时指标用于告警,不跨进程重启累计。启动期能力登记部分成功会在返回失败前关闭本地准入并尝试全量注销;Redis 持续不可达时,未确认的服务端记录只能依靠 TTL 与 Registry GC 排除。停机超时触发 task abort 后仍等待实际退出,再允许撤销 Registry。JobContext::parameter::<T>() 支持集合、映射和嵌套 JSON 参数,并执行结构安全门禁;非 JSON 参数由业务按声明 codec 从 payload() 解码。完整配置、边界和查询方式见 nadis README。
业务项目只声明 nasa,根据实际场景开启特性:
[dependencies]
nasa = { git = "https://github.com/nasa-runtime/nasa-runtime-rust.git", features = [
"web",
"mapper",
"mapper-redis-cache",
"tx",
"redis",
"cache",
"log",
"yml",
] }use nasa::mapper::{Mapper, Query};
use nasa::tx::transactional;
#[Mapper]
pub trait UserMapper {
#[Query("select id, name from users where id = #{id}")]
async fn find_by_id(&self, id: i64) -> sqlx::Result<Option<User>>;
}
#[transactional]
pub async fn save_user() -> anyhow::Result<()> {
Ok(())
}#[transactional] 嵌套调用默认复用外层 MySQL 事务。外层仍持有 Conn 时,内层再次取连接会立即
返回连接占用错误,避免当前任务等待自己释放连接守卫;应先让 Conn 离开代码块作用域或显式
drop(conn),再调用需要数据库连接的内层事务方法。完整事务传播、rollback-only 和连接生命周期
规则见 natx。
服务型项目推荐用声明式入口替代手写 main 装配:配置装载、组件启动/停机顺序、信号处理、优雅停机、 任务监督与配置热刷新全部由应用运行时接管,业务只声明组件与启动钩子:
application 同时提供业务初始化屏障:静态 #[nasa::initializer] 与启动 Hook 动态登记的
initializer 先合并冻结为一份依赖计划;migration 和出站依赖准备完成后再严格执行全部
before -> initialize -> after 三轮。全部成功前不开放入站监听、消费循环或服务发现。
需要在受监督任务结束后做一次性异步业务收尾时,可在 UserHook 使用
app.register_graceful_shutdown(priority, name, future)。数值越小越先执行,同一优先级按登记顺序执行;
任务集合只属于当前 Application,UserHook 关闭后不再接受新登记,Seal 时封存,并在业务资源释放前共享全局停机预算。任务
失败、超时或 panic 会进入停机报告并继续执行后续项,不覆盖已经确定的主错误。名称唯一、非空、不含控制
字符、URL、地址、凭据语义 token 或明显动态身份且不超过 128 个 UTF-8 字节。形态门禁不能证明实际业务基数,
也不按普通身份词前缀猜测未知字母串;调用方必须使用固定业务名称,不得拼接租户、请求或对象身份。
单个 Application 最多登记 256 项。完整执行位置和边界见
napp 的业务优雅停机任务章节。
[dependencies]
nasa = { git = "https://github.com/nasa-runtime/nasa-runtime-rust.git", features = [
"application", "log", "config-boot", "tx", "mapper", "mapper-redis-cache",
"redis", "cache", "web", "scheduling",
] }mod controller; // #[get_mapping] 等端点
#[nasa::application("log", "nacos-config", "db", "redis", "web", "scheduling")]
async fn main(app: nasa::Application) -> anyhow::Result<()> {
// 启动钩子:注册业务资源、登记受监督任务、注入路由或长连接定制。
app.register(MyService::new(app.datasource("default").await?))?;
Ok(())
}可声明组件:log、nacos-config、telemetry、db、redis、cache、partition、saga、kafka、
outbox、redis-job、grpc、auth、web、ws、nacos-discovery、discovery、scheduling。宏接受任意书写顺序,并按规范顺序
启动、严格反序停机;声明了但特性未编入时会在编译期能力探测处失败。saga 会隐式加入 db 与
outbox,业务入口无需重复声明这两个组件;为兼容显式依赖,三者同时写出也合法且语义相同。
hystrix、grafana、mapper 是门面 feature 或函数级能力,不是可声明组件。
详见 napp。
本节配置 Application 自己拥有的本地执行器。Redis 分区消费使用各 Redis 源配置内的
partition.executor,其 Runner 不进入这里的命名集合。
partition 支持命名 Runner 映射,也兼容把单个 default Runner 的字段直接写在根下。Runner 字段全部
可省略:省略项逐字段采用有界默认值,显式配置只覆盖对应字段;不同 Runner 的默认值和覆盖值互不影响。
partition:
default_runner: default
runners:
default: {}
settlement:
partitions: 8
global_inflight: 8192
critical: false容量、次数和时长必须为正数;*_ms 均以毫秒为单位,合法范围为 1..=31536000000(365 天)。
每个 Runner 先独立取得一份 RunnerConfig::default(),再用 YAML 中显式出现的属性逐项覆盖,因此业务侧
可以只写需要调整的键。以下表格覆盖解析器接受的全部属性:
| YAML 属性 | 类型 | 默认值 | 作用与约束 |
|---|---|---|---|
partition |
mapping | 无 | Partition 受管计划根;声明组件后必须提供该段,或在 UserHook 至少提交一个命名计划。partition: {} 是合法的扁平 default Runner 计划 |
partition.default_runner |
string | default |
app.partition() 选择的稳定名称;只能用于命名形态,且必须精确匹配 partition.runners 中的一项 |
partition.runners |
mapping | 无 | 稳定名称到隔离执行域的映射;命名形态必须有 1..=4096 项,不能与任何扁平 Runner 属性混用 |
partition.runners.<name> |
mapping | {} |
单个 Runner 的稀疏覆盖;名称不能为空、不能有首尾空格或控制字符,UTF-8 编码最多 128 字节 |
partition.runners.<name>.partitions |
integer | 可用并行度的两倍,再向上取 2 的幂并封顶 65536 | slot 和唯一 worker 数;输入范围 1..=65536,非 2 的幂会向上规范化,因此其它下限校验使用规范化后的值 |
partition.runners.<name>.queue_capacity_per_type |
integer | 65536 | 每个 (home, TaskType) 尚未进入 Running 的许可上限,覆盖入队、移动和 worker 暂存;范围为 1..=Tokio Semaphore::MAX_PERMITS |
partition.runners.<name>.queue_capacity |
integer | 同上 | queue_capacity_per_type 的兼容键,语义和边界完全相同;同一 Runner 同时声明两个键会拒绝整份候选配置 |
partition.runners.<name>.global_inflight |
integer | min(默认分区数 × 65537, Semaphore::MAX_PERMITS) |
当前 Runner 的延迟、排队、移动和执行中任务共享总上限;范围为 1..=Tokio Semaphore::MAX_PERMITS,不会被 partitions 的显式覆盖联动重算 |
partition.runners.<name>.max_type_states |
integer | max(4096, 默认分区数, 规范化后的 partitions) |
当前 generation 全部 (home, TaskType) 状态与指标基数上限;必须不少于规范化分区数,且不超过 1048576 |
partition.runners.<name>.max_lanes |
integer | 同上 | max_type_states 的兼容键,语义和边界完全相同;同一 Runner 同时声明两个键会拒绝整份候选配置 |
partition.runners.<name>.frozen_evidence_capacity |
integer | 1024 | 最近失败证据环保留条数;必须大于零,满后覆盖最旧样本但继续累计总数与覆盖数,样本不持有业务任务 |
partition.runners.<name>.max_inbound_tunnels |
integer | 64 | 单个目标 slot 同时登记的严格与非严格入站盗洞共享上限;必须大于零,登记名额通过原子门禁裁决 |
partition.runners.<name>.idle_task_threshold |
integer | 8 | 选择热点源、普通空闲目标和观察严格归还时使用的逻辑任务阈值;必须大于零,已有同向借入可为后来出现的严格热点复用目标 |
partition.runners.<name>.strict_opportunity_attempts |
integer | 2 | 每个已投递窃取请求独立保留给严格候选的最大安装次数;必须大于零,非严格候选不消耗这部分机会 |
partition.runners.<name>.return_observations |
integer | 3 | 严格盗洞发起归还前,任务边界和低负载条件必须连续成立的观察次数;必须大于零,任一轮不满足会重新累计 |
partition.runners.<name>.tunnel_lease_ms |
integer | 2000 | 非严格盗洞没有真实发布或消费进展时允许保持开放的最长时间;到期先停止新发布,再排空既有任务 |
partition.runners.<name>.load_observer_interval_ms |
integer | 1000 | Accepting 期间集中 observer 扫描全部 slot 负载的间隔;每轮按 slot 数量扫描,不按类型数量扫描 |
partition.runners.<name>.control_tick_ms |
integer | 1 | 活动严格迁移、归还、Moving 审计和停止推进的兜底间隔;完全空闲且没有控制责任时只等待事件,不按该值轮询 |
partition.runners.<name>.transition_timeout_ms |
integer | 5000 | 单笔物理移动允许保持 Moving 的最长时间;超时后停止猜测位置并关闭能够证明的最小故障域 |
partition.runners.<name>.shutdown_timeout_ms |
integer | 2000 | Application 为该 Runner 分配的总收口上限,仍受应用剩余绝对期限约束;受管停机先使用其中一半尝试无损排空,允许升级时剩余部分用于显式有损收口 |
partition.runners.<name>.drain_batch |
integer | 64 | worker 每轮从主队列、控制队列和各盗洞方向处理的最大批量;必须大于零,用于限制单一方向长期占用 worker |
partition.runners.<name>.critical |
boolean | true |
true 时该 Runner 的 Degraded 或 Failed 会使整体 readiness 失败并触发统一停机;显式设为 false 时只更新自身 readiness,不影响其它 Runner |
partition.runners.<name>.force_on_timeout |
boolean | true |
true 时无损阶段未收敛会由 Application 显式调用 force_stop;显式设为 false 时保留未收敛错误,不隐式中止运行中任务 |
扁平单 Runner 形态把表中 partition.runners.<name>. 后的字段直接放到 partition. 下,名称固定为
default。未知字段、零值、非法时长、缺失 default、非法名称或兼容键冲突会在创建 worker 前拒绝。
运行架构、UserHook 命名计划和停机语义见 napp Partition 受管模式。
submit_after 登记成功不保证未来一定执行:到期时仍会按当前类型容量和路由重新准入,稳定拒绝通过
Submission::await_outcome() 与 reason 返回。取消和到期重新准入竞争时只形成一个稳定终态,许可与
拒绝指标不会重复结算。
Partition 有两种生命周期所有者。直接使用 napart::PartitionRunnerRegistry 时,业务可在 Tokio runtime
运行期间按稳定名称动态 get_or_create 并 start,但必须共享同一个进程级注册表、限制名称总数并显式
停机;不同注册表中的同名 Runner 不共享顺序或容量。声明 Application 的 "partition" 组件时,YAML
和 Service UserHook 只负责提交启动期计划,全部名称在 Hook 结束时冻结,Prepare 统一启动并接管
readiness 与停机,Running 阶段不再追加受管 Runner。
initializer 适合装配动态路由与注册表、恢复业务状态、回填或预热依赖。它不是新的组件字符串,而是
application 生命周期中位于 Prepare 与 Seal 之间的固定阶段:
UserHook 登记 -> InitializerFreeze -> Prepare(migration / 出站门禁)
-> before 全局轮 -> initialize 全局轮 -> after 全局轮
-> Seal -> Ready 装配 -> 任务工厂与最终检查
-> 发布 Ready / 统一放行 -> 监听、消费与服务发现注册
属性入口可省略 name 和 order:默认名称从实现类型派生 canonical kebab-case,默认顺序为
100000。依赖边始终优先于 order;同一可执行集合中 order 越小越先执行,再按名称稳定裁决。
Service 启动 Hook 也可用 Application::register_initializer 登记已经构造的实例,两种入口共享同一份
名称唯一性、依赖环和顺序校验。
失败、panic、启动超时或取消都会阻止 Ready,并沿 active stack 严格逆序停止受管任务、撤销 initializer action 并关闭资源。框架不能撤销已经提交到 DB、Redis 或 Kafka 的外部事实,因此 initializer 必须可安全重跑:单库多步写使用事务,跨资源事实使用稳定幂等键或与 Outbox 同事务提交。 阶段耗时和失败按稳定 initializer 名称输出低基数指标;停机逐步骤事件与最终有界摘要可用于核对真实清理顺序。
完整宏属性、one-shot/hosted 边界、条件工厂和运行时示例见
napp 的业务 initializer 章节。
#[interceptor] 的 global 默认为 false,因此声明宏本身不会让拦截器自动执行。现有业务可以继续
在路由属性 interceptors(...),或在 app.configure_mapping(...) 内使用 plan.global(...)、
plan.scope(...) 精确控制
覆盖范围。只有显式写出 global = true,napp 才会在 Web Ready 阶段自动把它装配到当前 crate 中
符合该 interceptor 阶段合同的全部 *_mapping 端点:
use nasa::web::interceptor;
use nasa::web::{Next, Request, Response};
// 手动例子:默认 global=false。
#[interceptor(id = "manual-edge", kind = "edge", order = 10)]
async fn manual_edge(request: Request, next: Next) -> Response {
next.run(request).await
}
// 自动例子:main 不需要也不允许重复登记同一 binding。
#[interceptor(id = "automatic-edge", kind = "edge", order = 20, global = true)]
async fn automatic_edge(request: Request, next: Next) -> Response {
next.run(request).await
}
#[nasa::application("web")]
async fn main(app: nasa::Application) -> anyhow::Result<()> {
app.configure_mapping(|plan| Ok(plan.global(manual_edge::binding())))?;
Ok(())
}自动 global 只覆盖 *_mapping 自动端点,不覆盖 configure_router 添加的 Axum 路由,也不覆盖
/healthz、/readyz。自动函数只能无 State,或使用与 Router 根 State 相同的 State<T>;窄 State、
路径 scope、when_route 和动态开关仍应手动装配。自动和手动对同一 ID 发生重叠时,监听前审计会明确
报错,不会静默去重或执行两次。全部属性、阶段顺序和 binding 规则见
naweb README 与
naweb-macro README。
只开启业务需要的特性。宏包和底层实现包通常由 nasa 自动带出,应用无需直接依赖。
| 业务场景 | 建议特性 | 常用入口 |
|---|---|---|
| 应用入口与生命周期 | application |
#[nasa::application(...)]、nasa::Application |
| 业务初始化屏障 | application |
#[nasa::initializer(...)]、Application::register_initializer |
| HTTP 路由 | web |
nasa::web::{get_mapping, mvc_router} |
| 路由身份认证 | web-auth |
nasa::web::auth::{AuthProvider, AuthContext} |
| 路由双协议加密 | web-crypto |
nasa::web::crypto::{CryptoRuntime, KeyRing} |
| 遗留 RSA 私钥协议互通 | web-crypto-legacy-rsa |
编译期开关;仍需 provider 运行时显式允许 |
| 完整端点安全流水线 | web-security |
try_register_all、MappingRuntime、route policy |
| SQL Mapper | mapper |
nasa::mapper::{Mapper, Query, Insert, Update, Delete} |
| PostgreSQL SQL Mapper | mapper-pgsql |
nasa::mapper::pgsql::{Mapper, Query, Insert, Update, Delete};与 application 组合时复用受管 PgPool |
| SQLite SQL Mapper | mapper-sqlite |
nasa::mapper::sqlite::{Mapper, Query, Insert, Update, Delete};组合 application 由同一 db 组件管理文件来源 |
| SQLite 事务与迁移 | tx-sqlite |
nasa::tx::sqlite、nasa::migration::sqlite |
| SQLite Mapper L2 缓存 | mapper-redis-cache-sqlite |
共享 Redis L2 合同,缓存隔离实际文件 owner 与提交序号 |
| Mapper L2 缓存 | mapper-redis-cache |
#[Query(..., cache = true)] |
| PostgreSQL Mapper L2 缓存 | mapper-redis-cache-pgsql |
nasa::mapper::pgsql::{RedisMapperL2Cache, MapperL2Cache};与 MySQL 共享合同和进程默认注册槽 |
| MySQL 事务 | tx |
nasa::tx::{transactional, run} |
| PostgreSQL 事务 | tx-pgsql |
nasa::tx::pgsql::{transactional, run};与 application 组合时启用 PostgreSQL 数据源生命周期 |
| Saga 纯合同 | saga |
nasa::saga::{WorkflowDefinition, SagaOutcome} |
| Saga MySQL Runtime | saga-runtime |
managed #[nasa::application("saga", "web")]、SagaHandle、#[saga]、#[saga_workflow] |
| Saga PostgreSQL Runtime | saga-runtime-pgsql |
与 MySQL 相同的 managed 角色和四种数据面合同,数据源使用 PostgreSQL |
| Saga Kafka 数据面 | saga-kafka |
受管 command/result topic、consumer、publisher、broker ACK 与耐久 DLT;也保留 custom connector |
| Saga PostgreSQL Kafka 数据面 | saga-kafka-pgsql |
PostgreSQL 角色使用相同受管 Kafka 合同 |
| Saga Redis Streams command/result 托管 | saga-redis-stream |
SagaRedisStreamPublisher、SagaRedisStreamCommandConsumer、SagaRedisStreamResultConsumer |
| Saga PostgreSQL Redis Streams 托管 | saga-redis-stream-pgsql |
nasa::saga::pgsql 下相同 transport 类型 |
| Saga gRPC 协议与数据面 | saga-grpc |
两份原始 proto、generated client/server、mTLS 主体绑定、health 探测、封闭收据与受管装配 |
| Saga PostgreSQL gRPC 数据面 | saga-grpc-pgsql |
PostgreSQL 角色使用相同受管 gRPC 合同 |
| 消费去重 Inbox | inbox |
nasa::inbox::MySqlInbox |
| PostgreSQL 消费去重 Inbox | inbox-pgsql |
nasa::inbox::pgsql::PgInbox |
| 受管事务 Outbox | outbox |
nasa::application::{OutboxApplicationPlan, OutboxHandle} |
| PostgreSQL 受管事务 Outbox | outbox-pgsql |
同一 OutboxApplicationPlan 与按 driver 选择的持久后端 |
| 事务型业务审计 | audit |
nasa::audit::{MySqlOutboxAuditSink, TransactionalAuditSink} |
| OpenAPI 3.1 | openapi(配合 application + web) |
Application::openapi_document、ApiSchema、mapping 合同及 register_route_contract 显式动态合同;文档 path 包含实际 context_path |
| Secret/TLS 引用与两阶段轮换 | secret / secret-http / secret-vault |
RotatingSecretStore、RotatingTlsHttpClient、VaultKvV2Provider |
| OAuth/JWKS/Metadata | oauth |
nasa::oauth::{MetadataClient, JwksRegistry} |
| Schema Registry | kafka-schema-registry(蕴含 kafka、secret) |
独立 nasa::kafka::{ConfluentSchemaRegistry, ConfluentEnvelope};配合 application 用 app.schema_registry(name).await |
| 对象存储 | object-store(蕴含 secret) |
独立 nasa::object::{ObjectStore, S3ObjectStore};配合 application 用 app.object_store(name).await |
| gRPC listener | grpc |
nasa::grpc::{ServerPlan, GrpcServerConfig, GrpcServerHandle}、Application::register_grpc_service、#[application("grpc")] |
| Redis 命令、Stream、锁 | redis |
nasa::redis::RedisClient |
| 方法级 L1/L2 缓存 | cache |
nasa::cache::{cached, cache_invalidate} |
| 接口保护与 Prometheus/Grafana 面板 | grafana |
nasa::grafana::{grafana, Command, metrics} |
| 日志 | log |
nasa::log::LogManager |
| yml 配置加载与文件观察 | yml / yml-watch / config-boot |
nasa::yml、nasa::yml::watch、nasa::yml::nacos |
| 注册中心 | nacos / nacos-sdk |
nasa::discovery::nacos |
| 静态/DNS 服务发现 | discovery |
nasa::discovery::{StaticDiscovery, DnsDiscovery} |
| REST 负载均衡 | rest-discovery / rest-discovery-nacos |
nasa::discovery::rest |
| 长连接 | ws、ws-redis、ws-socketio |
nasa::ws::Server |
| 基础工具、加密、金额、图片 | base、crypto、numeric、image |
日期能力位于 nasa::base::date,其余使用对应同名模块 |
| 定时和异步任务 | scheduling、scheduling-cluster |
nasa::scheduling::{Async, scheduled} |
full 用于现有完整能力构建,full-pgsql 用于不带 MySQL runtime 的 PostgreSQL 完整持久能力;两者都
不是生产服务的默认选择。生产项目仍应只启用实际使用的 feature,以免扩大依赖、安全和运行责任。
# 业务项目 Cargo.toml——只依赖门面 nasa,按需开启特性
[dependencies]
nasa = { git = "https://github.com/nasa-runtime/nasa-runtime-rust.git", features = ["hystrix", "cache", "ws-redis", "rest-client"] }use nasa::hystrix::hystrix; // 有界隔离/超时/指标
use nasa::ws::Server; // WebSocket 服务端
#[nasa::web::get_mapping("/x")] // Axum MVC 风格路由同仓实现 crate 保留 registry 版本约束,工作区通过根级 patch 统一本地 package 身份。 公开归档使用 registry 依赖,前置版本必须可解析;本地 patch 不会随 crate 归档传递给使用方。
业务项目通过 crates.io 依赖门面 nasa:
[dependencies]
nasa = { version = "2.0.7", features = ["hystrix", "cache", "ws-redis", "rest-client"] }内部实现包使用工作区 Cargo.toml 中的 package name,例如 nabase、naimg、naws。
Cargo 包坐标不改变业务接口:门面模块仍是 nasa::base、nasa::date、
nasa::image 等。
启用 nasa/yml 后,业务通过 nasa::yml 使用 naml 的配置加载器和文档读写入口。
组件内的 YAML 解析与编码由 naml 封装;Kubernetes 认证和观测 controller 使用同一公开合同。
| 使用场景 | 入口 | 权限与失败边界 |
|---|---|---|
| 应用配置 | YmlLoader 或 strict::ConfigLoader |
合并来源、环境覆盖和表达式求值;严格入口固定来源权限,拒绝不完整候选 |
| 外部协议文档 | yaml::from_slice / yaml::to_string |
使用 serde_json::Value 保留原始字符串键;不执行 imports、环境替换或文件访问 |
| kubeconfig | nadisc-kubernetes 的显式认证来源 |
限制正文与累计文本为一 MiB;解析失败不创建认证客户端 |
| Prometheus 采集配置 | nafana-controller |
完整编码后复验 owner,再替换受管文件并请求 reload;编码失败不发布半份正文 |
读取要求单个 UTF-8 文档,普通别名按展开成本计费;重复键、merge key、未知标签和超限均拒绝。 外部入口允许数组及标量根,严格配置要求映射根并拒绝含糊路径键。编码保留值和类型,不保留注释、 排版或锚点名称,也不提供任意精度数字。错误不包含正文,调用方仍须控制诊断字段的展示权限。 具体预算、数值和字符串合同见 naml。
nasa::yml::strict 把主文件、profile、有序 imports 和固定环境快照装配成完整候选,支持
嵌套默认值、文件名通配符、目标类型绑定、字段来源解释与有界读取。通过启动前的
#[nasa::application("log", "web", config = configuration)] 显式选择严格工厂;
手动入口使用 ApplicationSpec::with_config_loader。工厂签名与完整入口见
Application 配置工厂。
application:
name: notification-service
log:
path: ${LOG_PATH:/usr/local/logs/${application.name}}
yml:
imports:
- file: /etc/conf/telegram*.yml
optional: false
- file: /config/*.yml
optional: true
config_watch:
enabled: true本地文件名支持 *、?,不递归进入子目录。每条模式按完整文件名自然排序:
config-2.yml 先于 config-02.yml,再到 config-10.yml;后者覆盖前者。
不同模式组、精确文件及远端文档仍保持声明位置,环境覆盖最后应用。必需模式零匹配失败,
可选缺失仍保留观察;坏格式、重复身份或读取期间的来源变化均拒绝候选。
${aa.bb.cc}、${aa-bb-cc}、${AA_BB_CC} 都能回退到环境 AA_BB_CC,确切树值和原样环境名优先,
空环境值仍属于命中。嵌套默认分支只在未命中时求值;环境原文不会再次解析。
严格环境与默认文本保留 String,再按目标字段受检绑定,避免密码 001234 被误作数值。
兼容 YmlLoader 保留原有加载范围,不自动执行 imports;默认值源码空白与字面键等差异需按
接入说明显式迁移。
启用 application,yml-watch 与上面的开关后,Service 观察实际来源和模式目录;事件合并与
15 秒周期补读进入同一候选流程,周期不是端到端生效期限。来源、权限和材料失败保留旧视图;
同值来源变化仍更新观察信息。配置快照版本、app.config_observation() 的来源序号、组件的
Applied / ApplyFailed / RestartRequired 分别表示不同事实,不承诺所有组件统一回滚。
冻结的 imports、环境、连接与信任根变化需要重启。完整边界见 naml、
配置中心装配 和运维。
根 README 只给组合方式;每个组件的完整字段、默认值、初始化代码和使用场景在各自 README 中维护。
#[nasa::application] 优先从非空环境变量 APP_CONFIG_FILE 指定的路径读取主配置,未设置或为空时使用 zcf/application.yml。支持绝对路径 APP_CONFIG_FILE=/etc/orders/application.yml,以及在项目根目录启动时的相对路径 APP_CONFIG_FILE=config/application.yml;所选文件必须存在,内容可为 {}。
下面是各组件读取的配置根:
application: # 仅启动期读取,远端不可改写
name: app
mode: auto # 可填 auto、service、batch;无 Web 的常驻服务应显式填写 service
log:
level: info,app=debug
path: logs/app
nacos: # 配置中心(nacos-config 组件),与服务发现独立
enabled: false
server_addr: 127.0.0.1:8848
group: DEFAULT_GROUP
database: # db 组件,多库使用 datasources.<name>
url: ${APP_MYSQL_URL}
max_connections: 16
saga: # saga 组件;managed 模式由 Application 装配运行时与协议端点
role: orchestrator
plan_mode: managed
database_bootstrap: application
service_identity: checkout-orchestrator
replica_identity: checkout-orchestrator-1
orchestrator:
datasource_ref: default
timer_poll_interval_ms: 500
timer_error_backoff_ms: 1000
timer_operation_timeout_ms: 5000
timer_failure_threshold: 3
definition_catalog:
mode: dynamic
datasource_ref: default
activation_policy: validated
watch_interval_ms: 500
capability_registry_ref: saga-participant-capabilities
publisher_authorization_policy_ref: saga-definition-publishers
api:
page_token_key_ref: saga-api-page-token
http:
enabled: true
authorization_policy_ref: checkout-saga-http-rbac
callers:
order-api:
credential_ref: saga-order-client
tenants: [system]
permissions: [start, read]
transport:
address_policies:
saga-participant-routing:
http_schemes: [https]
http_hosts: [inventory.internal, payment.internal]
http_ports: [443]
command_result:
kind: http
http:
shared_replay_claim: saga-http-replay
command_credential_ref: saga-command
result_credential_ref: saga-result
routing:
mode: capability-registry
address_policy_ref: saga-participant-routing
outbox: # outbox 组件,也由 saga 隐式纳入
datasource_ref: default
poll_interval_ms: 500
error_backoff_ms: 1000
operation_timeout_ms: 5000
batch_size: 100
failure_threshold: 3
redis: # redis 组件
url: ${APP_REDIS_URL}
namespace: app
profile: RustV2
cache: # cache 组件,通过 redis_ref 显式复用受管 Redis
mode: two_level
redis_ref: default
cache_ttl_secs: 300
null_ttl_secs: 30
invalidation:
enabled: false
scheduling: # scheduling 组件
cluster: leader # 可填 local、leader;leader 模式需要声明 redis 组件
leader_key: scheduled:leader
redis_ref: default
server: # web 组件
host: 0.0.0.0
port: 8080
context_path: /app
http2:
enabled: false # 显式开启后,同一明文端口接受 HTTP/1 与 h2c prior knowledge
ws: # ws 组件,独立于 server
addr: 0.0.0.0:9000
ws_addr: 0.0.0.0:9001
rest_discovery: # nacos-discovery 组件
enabled: false
provider: nacos手工装配(不使用应用运行时)的项目可自定根节点,启动顺序建议:
naml加载本地 yml、profile、环境变量并解析 import 描述;config-boot负责拉取远端配置并组装 overlay。nalog初始化日志。nadis初始化 Redis;natx/natx-pgsql/natx-sqlite按实际 driver 初始化数据库资源。namapper、cacheable注入缓存和数据源。nanacos、rest-discovery准备出站服务发现和 REST 负载均衡,此时不注册本实例。naweb装配路由,业务自行拥有 HTTP listener、协议选择与排空;naws启动长连接服务,nasched启动调度器。完成所有启动门禁、确认本实例 listener 实际可接流后,再向注册中心发布实例; 不能只凭端口已绑定提前注册。
#[nasa::application] 按规范组件顺序自动完成上述全部步骤,并补齐手工装配普遍缺失的部分:
信号处理、启动失败反向回滚、统一停机预算与配置热刷新;声明 "web" 时由 napp Web 组件启动受管
HTTP/1/h2c listener。
| 组件 | 门面模块或特性 | 主要场景 | 配置入口 |
|---|---|---|---|
| nasa | 门面包 | 统一导出所有业务能力 | 不直接读取 yml,按组件配置 |
| napp | application / rate-limit |
#[nasa::application] 生命周期编排,以及显式装配的跨副本 Redis 业务配额 |
application.* 及各组件配置根;配额参数由业务构造 |
| napp-macro | application |
#[nasa::application(...)] 属性宏与编译期校验 |
由 napp 运行时读取 |
| naml | yml / yml-watch |
有界 YAML 读写、嵌套表达式、自然排序导入、字段来源与目录观察 | yml.*、业务自定义根节点;外部文档不执行配置装配 |
| config-boot | config-boot |
启动期读取本地和远端配置 | nacos.*、nacos.imports |
| nanacos | nacos / nacos-sdk |
Nacos 配置、注册、发现、监听 | nacos.* |
| nadisc | discovery |
服务发现抽象、实例过滤、watch 契约 | discovery.* |
| nadisc-runtime | discovery-runtime |
任意 Rust 微服务的多注册中心 owner、共享观察、注册生命周期与有界停机 | discovery.* |
| nadisc-consul | discovery-consul |
固定 agent 注册、HTTP/TTL 检查与一致性健康发现 | discovery.connections.*.consul |
| nadisc-kubernetes | discovery-kubernetes |
Service/EndpointSlice 联合证据与只读发现 | discovery.connections.*.kubernetes |
| rest-discovery | rest-discovery |
lb://service REST 负载均衡调用 |
rest.* |
| rest-discovery-nacos | rest-discovery-nacos |
单 Nacos 注册发现和 REST 负载均衡组合 | rest_discovery.*;与配置中心的 nacos.* 分离 |
| rest-client-macro | rest-client |
声明式 REST 客户端宏 | rest_clients.* |
| naweb | web / web-security |
Axum 路由、interceptor 与端点安全运行时 | server.* 由 napp 读取 |
| naweb-macro | web |
MVC 风格路由注解和路由收集 | 编译期属性,无运行期配置 |
| namapper | mapper / mapper-redis-cache |
MySQL 声明式 SQL Mapper、动态 SQL、二级缓存 | database.*、datasources.*、sql.observability.*;L2 显式安装 |
| namapper-macro | mapper |
Mapper 派生和 SQL 注解宏 | 由 namapper 运行时读取 |
| namapper-core | runtime 内部合同 | 后端中立分页、排序、缓存合同、共享缓存运行时与结构化 SQL 节点 | 不读取业务配置 |
| namapper-sqlite | mapper-sqlite |
SQLite 声明式 SQL、动态绑定、流与 owner 隔离缓存 | 复用受管或 standalone SQLite 数据源 |
| natx-sqlite | tx-sqlite |
SQLite 文件权威、有界执行、事务、checkpoint 与备份 | datasources.<name>.driver: sqlite 与 sqlite.path |
| namigrate-sqlite | tx-sqlite 内部迁移门禁 |
SQLite 只读 validate、整批原子 apply 与历史保护 | 显式登记完整 Migrator,Application 在 Prepare 执行 |
| namapper-pgsql | mapper-pgsql / mapper-redis-cache-pgsql |
PostgreSQL Mapper、$n bind、动态 SQL、流式结果与 Redis L2 |
standalone 显式注册 pool;Application 模式复用受管 datasource |
| natx | tx |
ambient MySQL 事务、after-commit 回调、多数据源 | database.*、datasources.* |
| natx-core | runtime 内部合同 | datasource/driver catalog、owner、事务结果分类 | 不读取业务配置 |
| natx-pgsql | tx-pgsql |
PostgreSQL ambient 事务、命名 pool、SQLSTATE 分类 | 可显式建池,也可由 napp 从 YAML 受管 |
| natx-macro | tx |
#[transactional] 事务宏 |
由 natx 运行时读取 |
| nasaga-core | saga |
Saga 身份、definition、状态机、结果与补偿计划合同 | 无 I/O;definition 由业务注册 |
| nasaga-backend | runtime adapter 内部合同 | 后端中立行模型、分组 store 能力、封闭错误与 Saga/Inbox/Outbox/事务组合身份 | 无 SQLx driver,不执行 schema 自举 |
| nasaga-mysql | runtime 内部 store | Saga journal、CAS、timer fencing、参与方 gate 与 migration | 复用 natx MySQL pool |
| nasaga-pgsql | runtime 内部 store | PostgreSQL Saga journal、CAS、timer fencing、参与方 gate、治理与迁移资源 | 复用 natx-pgsql pool;原子写要求同源 ambient transaction |
| nasaga-runtime-core | backend wrapper 共享核心 | 唯一 Orchestrator/Participant 状态机、timer、恢复、transport 与治理计数 | 数据库事实由具体 store 提供 |
| nasaga-runtime | saga-runtime / saga-kafka / saga-redis-stream / saga-grpc |
Orchestrator、参与方事务 adapter、恢复管理、指标与受管 transport | 由业务注入 definition、受信 producer、路由与投递策略 |
| nasaga-runtime-pgsql | saga-runtime-pgsql 及 PostgreSQL transport feature |
组合 PostgreSQL Store/Inbox/Outbox/事务并复用唯一 Saga 状态机 | 可独立运行,也可交给 Application 托管 |
| nasaga-macro | saga-runtime |
#[saga] descriptor 和类型化参与方 adapter |
编译期属性,无运行期配置 |
| nadis | redis / redis-job |
Redis 单点或集群、nonce 幂等计数、普通 Stream/Proxy、有界微批、业务键有序分区消费、锁与分布式任务 | redis.*、redis.partition.*、redis.job.*;普通派生计划使用 redis_streams、redis_proxies、redis_pipelines |
| nadis-derive | redis-derive |
Redis Search 文档派生 | redis.search.* 由业务映射 |
| cacheable | cache |
L1/L2 缓存、刷新保护、失效广播 | cache.*、redis.* |
| nacache-macro | cache |
#[cached]、#[cache_invalidate] |
由 cacheable 运行时读取 |
| naidempotency | nasa::idempotency |
幂等状态机、首次执行、重放与冲突裁决 | 无固定 yml;由业务注入 store |
| naidempotency-mysql | idempotency-mysql |
与业务事务共享记录或提供持久响应重放 | 复用 database.* |
| naidempotency-pgsql | idempotency-pgsql |
PostgreSQL 租约 fencing、持久重放与命名 datasource | 复用显式或受管 natx-pgsql pool |
| naidempotency-redis | idempotency-redis |
有 TTL 的跨副本响应重放 | 复用 redis.* |
| naoutbox-core | nasa::outbox |
Outbox 事件、发布端、保序投递与持久 adapter 角色合同 | 无运行期 yml |
| naoutbox-mysql | outbox |
同事务写事件、单 owner dispatcher、可选死信 | 复用 database.* |
| naoutbox-pgsql | outbox-pgsql |
PostgreSQL 同事务追加、fenced dispatcher、lane、配额与保留 | 可独立使用;Application 负责受管 dispatcher 生命周期 |
| nainbox-core | inbox 内部合同 |
后端中立消费去重与事务结果裁决 | 无运行期 yml |
| nainbox-mysql | inbox |
Inbox 标记与业务副作用同事务 | 复用 database.* |
| nainbox-pgsql | inbox-pgsql |
PostgreSQL Inbox 标记与业务副作用同事务 | 复用显式或受管 natx-pgsql pool |
| naaudit | audit |
脱敏业务审计事件与事务型 sink 合同 | 无独立配置根 |
| naaudit-mysql | audit |
审计事件写入同事务 MySQL Outbox | 连接使用 database.* 或 datasources.*;受管 sink 使用 audit_sinks.* |
| naaudit-pgsql | audit-pgsql |
审计事件写入同事务 PostgreSQL Outbox | 连接使用 database.* 或 datasources.*;受管 sink 使用 audit_sinks.* |
| hystrix | hystrix |
有界隔离、超时、指标流;可选 Application 命令目录与有序关闭 | hystrix.enabled、hystrix.isolation、hystrix.commands |
| hystrix-macro | hystrix |
#[hystrix] 与 #[global_fallback];受管命令缓存随应用实例切换 |
由 hystrix 运行时读取 |
| nafana | grafana |
接口隔离、Prometheus 指标、Grafana 原生自适应接口墙 | grafana.*、/metrics |
| nafana-macro | grafana |
#[grafana] 编译期参数校验与包装 |
无运行期 yml |
| nametrics-core | application 内部合同 |
单一指标目录、冲突审计、同源 Prometheus/OTLP 快照与样本拒绝诊断 | 无运行期 yml |
| natelemetry | telemetry 内部运行时 |
W3C flags 继承、exporter 唯一根采样裁决、有界 span 队列,并由 napp 管理 OTLP trace/metrics 停机 flush |
telemetry.* 由 napp 读取 |
| nasched | scheduling / scheduling-cluster |
异步任务、定时任务、Redis 集群去重 | scheduling.* |
| async-macro | scheduling |
#[Async]、#[scheduled] 宏 |
由 nasched 运行时读取 |
| napart | partition |
命名 Runner 隔离、严格 FIFO 的保序任务窃取、有界背压、延迟稳定终态与可证明停机 | 直接模式运行期动态创建并显式停机;Application 模式由 YAML/UserHook 提交启动期计划 |
| naws | ws / ws-client / ws-redis / ws-socketio / ws-kafka |
受管 TCP/WebSocket 协议宿主、原生 Client、鉴权、广播、共享接收预算与真实退出等待 | 入站 ws.*;命名出站 ws_clients |
| naws-proto | ws |
typed 与动态 schema、四种 ProtocolBytes 模式及有界 JSON 转换 | 显式 Mode 与 schema,无独立配置根 |
| naws-proto-derive | ws |
协议结构体派生 | 网络配置由 naws 读取 |
| nafka | kafka / kafka-schema-registry / kafka-mysql-checkpoint |
多数据源与独立producer lane、有界按键消费、组内多owner、安全确认、同集群消费/输出/位点事务、LSO 冻结回放、持久 checkpoint、单目标原文转发和有限DLT回投/原文隔离;可选单主 MySQL 跨语言共享进度,以及 Confluent envelope、批准 ID 映射与有界 schema client | Kafka 用 kafka.* / kafkas.*;事务通过 transact 固定部署身份与白名单;受管 Registry 用 schema_registries.<name>,独立 client 与 MySQL checkpoint 显式构造 |
| nafka-macro | kafka |
#[kafka_consumer] 静态收集 |
由 Kafka 运行时读取 |
| ncrypto | crypto |
现代令牌加密和受控兼容加解密 | crypto.*、环境变量承载密钥 |
| nanum | numeric |
定点金额、价格、最小变动单位对齐、舍入 | numeric.* |
| naimg | image |
图片压缩、尺寸裁剪、格式转换 | image.* |
| nalog | log |
控制台和文件日志、级别热切换 | log.* |
| nabase | base |
BaseResponse、日期时间、ByteSize、Snowflake、字符串、环境变量和翻译抽象 | base.*;日期配置由业务投影 |
| nabudget | REST/Web 内部合同 | 绝对 deadline 与取消树 | 无运行期 yml |
| namigrate | application + tx |
MySQL migration validate/apply 门禁 | database.migrations |
| namigrate-core | runtime 内部合同 | 后端中立 migration 状态比较与封闭失败分类 | 不读取业务配置 |
| namigrate-pgsql | tx-pgsql 内部迁移门禁 |
PostgreSQL migration validate/apply、session advisory lock 与非事务完成证据 | standalone 显式调用;Application 在 Prepare 执行 |
| naopenapi | openapi |
从已审计路由事实生成确定性 OpenAPI 3.1 | application.* 文档信息 |
| naauthz | application + web 内部合同 |
同代 route 策略、未命中缺省与 generation 的完整快照,以及 fail-closed 对象授权 | 策略由代码或外部 provider 注入 |
| nauth-oauth | oauth |
JWT、JWKS 与授权服务器 metadata | auth.* 由 napp 读取 |
| nasecret | secret |
分片解析、脱敏快照与两阶段轮换 | secrets.* |
| nasecret-http | secret-http |
随 secret 代际轮换的 TLS/mTLS HTTP client | 引用 secrets.* ID |
| nasecret-vault | secret-vault |
有界 KV v2 secret provider | provider 配置由业务投影 |
| naobject | object-store |
有界对象合同与 S3-compatible adapter | 受管模式用 object_stores.<name>;独立 adapter 显式传入 options |
| nagrpc | grpc / grpc-discovery |
统一 codegen/service registry、HTTP/2/TLS、具名发现调用、健康、反射、方法策略、观测与排空 | listener 使用 grpc.*,动态客户端使用发现 owner;可独立构造或交给 Application 托管 |
| nagrpc-build | grpc 的 build dependency |
vendored protoc、descriptor/摘要、受管 server adapter 与兼容门禁 | 只写 Cargo OUT_DIR |
| macro-support | 宏内部依赖 | 过程宏路径解析 | 无运行时 yml |
-
ncrypto的弱加密只用于受控兼容既有密文协议,不适合作新系统的机密性边界。 为逐字节对齐既有服务,ncrypto 保留了 AES-ECB、CBC(IV=Key)、RSA 的 PKCS#1 1.5 填充、 以及"用 RSA 私钥做保密"等已知弱的构造。只用于与既有系统互操作;新系统请用nasa::crypto::encrypt_modern/decrypt_modern这类现代入口,不要复用这些兼容函数。现代入口默认使用 随机盐 + Argon2id + AES-256-GCM,返回自描述NC2.*令牌;业务可用 AAD 绑定租户或记录上下文。 既有 PBKDF2-HMAC-SHA256 的NC1.*仅保持兼容读取,错误口令、AAD 错配或密文篡改都会失败。 -
rsa0.9 计时侧信道(RUSTSEC-2023-0071,Marvin 攻击)当前没有上游安全更新。 由 ncrypto 引入。默认构建只保留 RS256 公钥验签等不执行易受攻击私钥解密的能力;兼容格式 采用 PKCS#1 1.5 填充的私钥解密与私钥 type-1 运算受专用编译 feature 和 Web 运行时开关双重隔离, 且不进入full。deny.toml仍按包级 advisory 显式登记,待上游提供安全更新后移除。 -
拒绝服务攻击防护与资源上限(默认已提供保守兜底,可按部署调整):
ws:ServerConfig.max_connections(连接总数,accept 处背压)、max_unauthenticated(未认证连接数,防慢握手/慢鉴权占满连接池)、max_inflight_handlers(全局) 与max_inflight_handlers_per_conn(单连接配额,防单连接抢占全局池)。partition:每个命名 Runner 独立限制类型排队、全局在飞、类型基数和入站盗洞;submit的 满载、停机和隔离失败对调用方可见,submit_async提供等待容量的真背压;已登记 delayed 任务到期拒绝同样形成可等待的稳定终态。image:输出像素上限(MAX_OUTPUT_PIXELS)防解压炸弹式放大。
组件 crate 与 .crate 归档只携带产品源码、公开文档和再分发所需文件。真实后端连接信息只能由部署
环境注入,不得把内网地址、账号或密码写进说明文档或配置样例。
| 文档 | 用途 |
|---|---|
| 快速开始 | 业务应用如何依赖 nasa、选择特性、配置 yml 和编写最小示例。 |
| 架构说明 | 生命周期、事务消息、有序执行及安全边界。 |
| 接入与升级 | 线上依赖、资源所有权、配置与持久数据的接入约束。 |
| 部署指南 | 应用模式构建、配置注入、容器信号、健康端点和接流条件。 |
| 运维指南 | 运行状态、退出码、停机顺序、配置刷新和故障排查。 |
| Saga 生产指南 | Saga 事务边界、消息合同、恢复治理与生产准入条件。 |
| 交付就绪清单 | 产品归档、组件边界和生产环境批准条件。 |
| 贡献指南 | 贡献规则、文档、注释和代码维护约束。 |
| 安全说明 | 安全报告方式、敏感面和默认安全策略。 |
采用双许可证:MIT 或 Apache-2.0,二选一。