在单独的线程中运行东西并不一定会让它们运行得更快。
在单机上运行的系统的吞吐量受到机器的处理带宽的限制;即内核的数量和速度、内存系统、磁盘和网络 I/O 等。在多线程应用程序中,所有线程都有效地共享资源。因此,例如,如果您在给定时刻拥有比核心更多的可运行线程,则某些线程将等待被调度到代码中。
第二个问题是线程通常需要相互通信和/或更新共享数据结构。这两者都需要某种同步。如果你有很多这样的事情发生,同步就有可能成为降低吞吐量的瓶颈。
那么这如何应用于您的系统呢?好吧,潜在的问题是正在执行后台处理的额外线程将使用资源,如果线程的工作过多: - 它们可能无法跟上,队列长度可能会超出控制,导致长时间的延迟甚至更糟,并且 - 这可能会干扰听众接受新消息的能力。
从性能的角度来看,您要避免的一件事是线程过多。超过某个点(取决于应用程序),添加更多线程实际上会由于各种原因而降低吞吐量。根据经验,尽量将线程数限制为内核数的 1 到 2 倍。
如果您认为您的系统可能会被更多可以处理的消息淹没,则需要对其进行设计以减轻负载;例如,通过停止接受新请求或转储现有请求。您不想要无限的队列或无限数量的工作线程,这些可能会导致灾难性的反馈和系统在重负载下崩溃/崩溃。(还要注意,由于未检测到的并发错误,重负载会导致更多的争用并增加失败的机会。)
更新:
- 似乎 AMQP 具有使用“流帧”的内置流控制机制。您可能应该尝试利用它,而不是在内部进行自己的流量控制/负载管理。
- 消息持久性本身无济于事。虽然您可以缓冲大量消息流量,但它无法帮助您处理消息生成和处理速率之间的不匹配。(持久性机制也会导致消息传输速率变慢,尽管这可能不是您关心的问题。)
- 对不同服务进行单独的处理阶段可以提高吞吐量,但另一方面是您有更多的消息传递开销。底线是这种分区会减少而不是增加吞吐量。
- 如果您希望您的解决方案扩大规模,您需要对其进行设计,以便您可以复制您的服务器;例如,与其将新请求发送到一台服务器,不如将它们拆分到具有独立持久性后端的 N 台服务器上。