2

我正计划编写一个“彗星”服务器,用于向客户“流式传输”数据。过去我增强了一个以利用多核 CPU,但现在我从头开始。我打算使用 epoll/kqueue 或 libevent 为服务器供电。

我一直在权衡的问题之一是使用什么服务器设计?我有几个可用的选项,因为我计划使用多进程模型来利用所有 CPU 内核。

  1. 预分叉的多进程 - 每个进程都有自己的接受
  2. 带有主进程的预分叉多进程 - 主进程接受然后使用描述符传递将接受的套接字传递给进程
  3. 具有不同端口的预分叉多进程 - 每个进程侦听同一系统上的不同端口。负载均衡器根据来自各个守护进程的一些负载反馈来决定哪个进程获得下一个连接

设计#2 是最复杂的。设计#3 很简单,但无论设计如何,我都需要额外的硬件,因为我将在多台机器上运行它,并且无论如何都需要负载均衡器。设计#1 有雷群问题,但我想雷群对于 8 个进程来说并不是什么大问题,但是当客户端不断连接和断开连接时它就变得很重要(这应该很少见,因为这是一个彗星服务器)。

正如我所看到的,#2 很复杂,并且需要 2 个额外的系统调用,因为描述符在每个接受的主从进程之间传递。将这种开销与雷鸣般的羊群问题相对会更好吗?如果我有 8 个进程唤醒并执行接受,我是否可能会看到 8 个接受调用,以防我使用设计#1?

我的设计选择的优缺点是什么?你会推荐什么?

4

2 回答 2

0

如果您的目标是制作一个非常大规模、高吞吐量的 HTTP 守护程序,那么 #1、#2 和 #3 都不合适。如果你想获得可伸缩性,最好使用多线程的 1-to-m 或 m-to-n 模型,就像 nginx/lighttp 那样。

事实上,如果您希望程序在一秒钟内处理少于一百个连接,那么#1、#2 和#3 可能不会产生任何明显的差异。

但是,如果您将来可以通过将进程切换到线程来扩展程序,我会选择 #2,因为它可以轻松地集成到 1 到 m 或 m 到 n 处理模型中。

于 2011-11-22T00:07:05.143 回答
0

如果不是进程而是线程,我会选择选项 2。无论如何,这对我来说看起来很昂贵,所以我们要在 1 和 3 之间进行选择。

如果可以以某种方式估计预期负载,我更喜欢 1。您能否为休眠群体的大小设置一个上限,例如预分叉进程?您需要多快才能接受新连接?

所以如果你要走汤姆·邓森的路,带着大群快速越过红河到堪萨斯,你可能需要选择第三种方式。所以无论如何资源都是可用的......

于 2011-11-21T19:01:49.140 回答