本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。
设计
ruststream-nats 所处的位置:在 RustStream 运行时与 async-nats 客户端之间,所有订阅和发布者都在同一个连接上。
以文字阅读本图
- 你的服务: #[subscriber] 订阅者处理器; RustStream::new(..) .with_broker(..)
- RustStream 核心: 运行时:分发、工作分区、结算、重试
- ruststream-nats: NatsSubscriber 产出 NatsMessage; NatsPublisher, JetStreamPublisher; 上下文键; 进程内传输; NatsBroker 一个连接; CoreSubject, CoreWildcard, JetStreamSubject
- async-nats: 客户端上的 jetstream::Context; Client:一个连接
- #[subscriber] 订阅者处理器 → 运行时:分发、工作分区、结算、重试: 挂载到
- 运行时:分发、工作分区、结算、重试 → NatsSubscriber 产出 NatsMessage: 轮询流
- NatsSubscriber 产出 NatsMessage → Client:一个连接
- NatsPublisher, JetStreamPublisher → Client:一个连接
- Client:一个连接 → NATS 服务器
本 crate 在 async-nats 之上实现核心的 Broker trait,不给协议增加任何东西。它上面的运行时对每个 Broker 都相同。NATS 特有的一切都在本 crate 里:描述符、ack 的含义、重试副本发往何处,以及投递的元数据。
已连接的 Broker 持有一个客户端,由它配对出的每个发布者都共用这个客户端。一个 Core 订阅就是连接上的一次订阅。一个 JetStream 订阅创建一个拉取消费者,并通过同一个连接读取它的消息。因此,服务按处理器和按发布选择 Core 还是 JetStream,而不是按进程选择。
JetStream 上下文建立在 Broker 连接时所在的运行时上。客户端为它启动的任务,即消费者的拉取循环和确认任务,无论哪个线程发出请求,都在那里运行。
本 crate 没有为之提供类型的设置,就是一个 async-nats 连接选项,由 with_options 在任何拨号之前附加。client 和 jetstream 交出客户端和一个 JetStream 上下文,用于本 crate 没有封装的操作,比如创建流。from_client 接管一个在别处构建的客户端。
进程内传输
启用 testing 特性后,TestApp::start 把同一个 Broker 连接到进程内传输,而不是服务器。描述符、策略和投递都是生产环境中的那些。它用 * 和 > 匹配 subject,让队列组分担消息,用 "no responders" 应答请求,并保存流及其序号、去重窗口和发布所声明的预期。它的消费者从各自的投递策略开始投递,报告元数据,并像服务器那样结算、延迟,以及在 ack_wait 之后重新投递。
属于服务器本身的东西留给真实服务器上的运行:流的 subject 列表和上限、max_ack_pending、订阅的等待上限、认证和 TLS。在进程内,订阅能找到它指定的每个流;对着服务器时,不存在的流会让启动失败。
不启用该特性时,这个传输不参与编译。生产构建中已连接的 Broker 就是一个指向连接的共享指针,编译器会检查这个大小。