常见问题

部署

  • 什么是 nsqd 的推荐拓扑结构?

    我们强烈推荐在任何生产消息的服务旁边运行一个 nsqd

    nsqd 是一个相对轻量级的进程,具有有界的内存占用,这使得它非常适合“与其他进程友好共处”。

    这种模式有助于将消息流结构化为消费问题,而不是生产问题。

    另一个好处是,它本质上为给定主机上的该主题形成了一个独立的、分片的、孤立的数据存储。

    注意:这并不是绝对的要求,只不过更简单(参见下面的问题)。

  • 为什么生产者不能使用 nsqlookupd 来查找发布消息的位置?

    NSQ 采用消费者端发现模型,这减轻了预先配置消费者查找所需主题位置的负担。

    然而,它并没有提供任何手段来解决服务应该发布到哪里的问题。这是一个鸡蛋问题,在第一次发布之前,主题并不存在。

    通过将 nsqd 与之共置(参见上面的问题),您完全避开了这个问题(您的服务只需发布到本地的 nsqd),并允许 NSQ 的运行时发现系统自然工作。

  • 我只想在单节点上将 nsqd 用作工作队列,这是一个合适的用例吗?

    是的,nsqd 可以独立运行得很好。

    nsqlookupd 在较大的分布式环境中很有益处。

  • 我应该运行多少个 nsqlookupd

    通常只需几个,具体取决于您的集群大小、nsqd 节点和消费者的数量,以及您期望的容错能力。

    对于涉及多达数百个主机和数千个消费者的部署,3 个或 5 个运行得非常好。

    nsqlookupd 节点在回答查询时不需要协调。集群中的元数据是最终一致的。

发布

  • 我需要客户端库来发布消息吗?

    不需要!只需使用 HTTP 端点进行发布(/pub/mpub)。它简单、易用,并且在几乎任何编程环境中都无处不在。

    事实上,绝大多数 NSQ 部署都使用 HTTP 进行发布。

  • 为什么强制客户端处理 TCP 协议的 PUBMPUB 命令的响应?

    我们认为 NSQ 的默认操作模式应该优先考虑安全性,并且我们希望协议简单且一致。

  • PUBMPUB 何时会失败?

    1. 主题名称格式不正确(不符合字符/长度限制)。参见 主题和通道名称规范
    2. 消息太大(此限制作为参数暴露给 nsqd)。
    3. 主题正在被删除过程中。
    4. nsqd 正在干净退出过程中。
    5. 发布期间的任何客户端连接相关失败。

    (1) 和 (2) 应被视为编程错误。(3) 和 (4) 很少见,而 (5) 是任何基于 TCP 的协议的自然部分。

  • 我如何缓解上面的场景 (3)?

    删除主题是一个相对不频繁的操作。如果您需要删除主题,请协调时机,使得在删除后经过足够时间之前,不会执行导致主题创建的发布操作。

设计与理论

  • 您如何推荐命名主题和通道?

    主题名称应描述流中的数据

    通道名称应描述其消费者执行的工作

    例如,好的主题名称有 encodesdecodesapi_requestspage_views,好的通道名称有 archiveanalytics_incrementspam_analysis

  • 单个 nsqd 支持的主题和通道数量有什么限制吗?

    没有内置限制。它仅受主机上运行 nsqd 的内存和 CPU 限制(每个客户端的 CPU 使用量在 issue #236 中已大大降低)。

  • 新主题如何向集群公告?

    第一个针对主题的 PUBSUB 将在 nsqd 上创建该主题。然后,主题元数据将传播到配置的 nsqlookupd。其他读取器将通过定期查询 nsqlookupd 来发现此主题。

  • NSQ 可以做 RPC 吗?

    是的,这是可能的,但 NSQ 并非针对此用例设计。

    我们打算发布一些关于如何构建此结构的文档,但在此期间,如果您感兴趣,请联系我们。

pynsq 特定

  • 为什么您强制我使用 Tornado?

    pynsq 最初旨在作为消费者焦点库,而在 Python 中实现消费 NSQ 协议,使用异步框架要简单得多(特别是由于 NSQ 的推送导向协议)。

    Tornado 的 API 简单且性能合理。

  • 发布时是否必须使用 Tornado IOLoop?

    不,nsqd 暴露了 HTTP 端点(/pub/mpub),用于简单、无语言相关的发布。

    如果您担心 HTTP 的开销,不要担心。此外,/mpub 通过批量发布(原子方式)减少了 HTTP 的开销。

  • 那么,我何时会想使用 Writer

    当高性能和低开销是优先级时。

    Writer 使用 TCP 协议的 PUBMPUB 命令,与其 HTTP 对应物相比,开销更小。

  • 如果我只想“发射并忘记”(我可以容忍消息丢失!)?

    使用 Writer 并不为 publish 方法指定回调。

    注意:这使客户端代码更简单,在幕后 pynsq 仍需处理来自 nsqd 的响应(即这样做没有性能优势)。

特别感谢 Dustin Oprea (@DustinOprea) 启动了这个 FAQ。