Enterprise 版本
计量
NextPDF Enterprise 在 PHP 编排层收集使用计量——操作数、已处理页数、时长——用于计费与审计。条目先在内存中缓冲,按批刷新到一个或多个后端,且某个后端的失败绝不会阻塞处理。本页描述可观察的计量行为与公共契约。
可用性与授权
标题为“可用性与授权”的章节此能力随 NextPDF Enterprise(nextpdf/enterprise)发行,并通过 Enterprise 层级的授权信封激活。没有该授权项的部署不会加载此能力的类。计量是一项 Enterprise 基础能力,没有单独的每功能标志。比较版本并获取授权。
概念概述
标题为“概念概述”的章节计量收集器为每次操作记录一条不可变条目:一个操作类型、一个单位计数、一个时间戳、租户与授权标识符、已处理页数、操作时长,以及自由格式的元数据。条目会在一个内存缓冲区中累积。当缓冲区达到其配置的大小时会自动刷新;你也可以显式刷新,并且可以注册一个关闭处理器,使 PHP-FPM 工作器在请求结束时刷新任何余量。一个长期运行的工作器(例如 Octane 或 Symfony 工作器)则应改为按周期性定时器刷新。
报告器将一个批次扇出到一个或多个后端。后端是隔离的:某个后端的失败不会阻止其他后端接收该批次。每次后端投递最多重试到配置的尝试次数;若所有尝试都失败,针对该后端的批次会被记录并丢弃——按设计,计量是尽力而为且非致命的,因此一次计量中断绝不会降低文档处理。后端是计量后端接口的任意实现——一个 Prometheus 推送目标、一个计费 API、一个数据库或一个队列——并且实现被要求是幂等的,以便一个重复的批次能被妥善处理。
这种编排层级的计量用于计费与审计可见性。它有意不作为配额强制执行的权威来源;配额决策在部署中的别处依据一个权威的用量数据作出。
为何如此设计
标题为“为何如此设计”的章节计量位于计费与审计路径上,而非文档处理路径上,这种分离是刻意为之。每次 record 调用都会向内存缓冲区追加一条不可变的 MeterEntry,因此捕获用量始终是一个 O(1) 操作。刷新按批进行,扇出到 MeteringBackendInterface 契约之后的隔离后端。这样一来,一个缓慢或失效的计费端点会优雅降级,而一个用尽尝试的批次会被记录并丢弃,而非抛出。因此一次计量中断绝不会拖住高吞吐工作,也不会与文档吞吐争抢资源。其代价是编排层计量为尽力而为且非权威——所以配额强制执行由别处依据一个权威数据决定。
设计背景:高吞吐文档生成。
公共 API 表面
标题为“公共 API 表面”的章节composer require nextpdf/enterprise:^3受支持的集成点是计量收集器(record、flush、bufferCount、registerShutdownFlush)、计量报告器(report)、计量后端接口(report、isHealthy、backendName),以及不可变的计量条目值对象。为了生产环境的耐久性,提供一个重试安全、幂等的后端实现是你的责任。
代码示例——快速开始
标题为“代码示例——快速开始”的章节use NextPDF\Enterprise\Metering\MeterCollector;use NextPDF\Enterprise\Metering\MeteringReporter;
$collector = new MeterCollector(new MeteringReporter([$backend]), bufferSize: 100);$collector->registerShutdownFlush(); // PHP-FPM: flush remainder at request end
$collector->record( operation: 'parse', count: 1, tenantId: $tenantId, licenseId: $licenseId, pagesProcessed: 12, durationMs: 84.0,);代码示例——生产环境
标题为“代码示例——生产环境”的章节use NextPDF\Enterprise\Metering\MeteringReporter;
// Multi-backend fan-out with retry and failure isolation.$reporter = new MeteringReporter( backends: [$prometheusBackend, $billingApiBackend], maxRetries: 3, logger: $logger,);
// A failing billing API does not stop Prometheus from receiving the batch;// exhausted retries are logged and the batch is dropped — never thrown.$collector = new MeterCollector($reporter, bufferSize: 500);边界情况与陷阱
标题为“边界情况与陷阱”的章节- 刷新是幂等的。 对一个空缓冲区调用
flush是一个空操作;重复刷新是安全的。 - 后端失败是非致命的。 用尽重试会记录一条错误并丢弃该后端的批次;调用仍然正常返回。请勿依赖计量来做硬性配额强制执行。
- 至少需要一个后端。 用空后端列表构造一个报告器会被拒绝。
- 幂等性是后端的职责。 接口契约要求后端去重(按时间戳、操作与租户)——一个重试或重复的批次绝不能重复计数。
- 工作器模型很重要。 对 PHP-FPM 使用关闭处理器;对长期运行的工作器使用周期性定时器刷新,否则条目会一直缓冲到工作器退出。
record 是一次 O(1) 的缓冲追加。刷新成本与批次大小及后端数量成正比;通过缓冲与关闭处理器,它被移出了请求路径。重试按后端应用,并受配置的尝试次数限定。
安全说明
标题为“安全说明”的章节计量条目携带租户与授权标识符以及操作元数据。请将元数据视为可能敏感,并根据你的合规要求限定你的后端存储与留存范围。租户与授权标识符必须来源于经过认证的上下文。
符合性
标题为“符合性”的章节计量在公共边界上不定义自己的线路格式——后端接口将序列化委托给每个后端实现(例如,一个 Prometheus 推送目标遵循 Prometheus 暴露约定)。在此表面上不主张任何外部标准;本页没有 RAG 引用,因为没有规范性规范支配该进程内收集器契约。
行为契约
标题为“行为契约”的章节- 收集器为每次操作记录一条不可变条目,并在一个内存缓冲区中累积条目,缓冲区会在其配置的大小处自动刷新;也提供显式刷新与一个关闭刷新处理器。
- 刷新是幂等的:刷新一个空缓冲区是一个空操作,重复刷新是安全的。
- 报告器将一个批次扇出到一个或多个后端,且各后端相互隔离;某个后端的失败不会阻止其他后端。
- 每次后端投递最多重试到配置的尝试次数;用尽重试会被记录并丢弃——计量是尽力而为的,绝不会向处理路径抛出异常。
- 用空后端列表构造一个报告器会被拒绝;后端被要求是幂等的,以便一个重复的批次不会重复计数。
record是一次 O(1) 的缓冲追加;刷新成本与批次大小及后端数量成正比,并被保持在请求路径之外。
发布边界
标题为“发布边界”的章节本页仅记录外部可观察的行为与受支持的公共 API 表面。内部命名空间路径、辅助类、机制表、运行手册文件名与工单前缀不在范围内。
Core 回退
标题为“Core 回退”的章节NextPDF Core(Apache-2.0)没有计量收集器、报告器或后端表面——没有;此能力没有 Core 层级的等价物。NextPDF 不对 Core 处理进行计量。
Pro 回退
标题为“Pro 回退”的章节NextPDF Pro 没有计量表面——没有;此能力没有 Pro 层级的等价物。计量收集器、报告器与后端接口仅发行于 nextpdf/enterprise 软件包中。
Enterprise 边界说明
标题为“Enterprise 边界说明”的章节缓冲区生命周期、扇出、重试与隔离在行为层面描述。后端接口将序列化委托给每个后端实现;内部缓冲的内部实现与任何内部扇出细节不在公共表面的范围内。
部署边界
标题为“部署边界”的章节运维方负责后端实现、它们的耐久性与幂等性、计量元数据的留存与存储范围,以及工作器模型的刷新策略(PHP-FPM 用关闭处理器,长期运行的工作器用周期性定时器)。一次计量后端中断绝不会降低文档处理。租户与授权标识符必须来源于运维方所配置的经过认证的上下文。
法律合规边界
标题为“法律合规边界”的章节计量表面不适用任何出口管制限制。计量元数据可能敏感;留存与存储范围是运维方的合规责任。本文档不是法律意见;请咨询你自己的合规与法律顾问。