我计划写一个'comet'服务器'流'数据到客户端。我在过去已经增强了一个,以利用多核cpu,但现在我从头开始。我计划使用epoll/kqueue或libevent来为服务器供电。
我一直在考虑的一个问题是使用什么服务器设计?我有几个可用的选项,因为我计划使用多进程模型来利用所有的CPU内核。- 预分叉多进程-每个进程做它自己的接受
- 带有主-主进程的预分叉多进程接受,然后使用描述符传递将接受的套接字传递给进程 具有不同端口的预分叉多进程-每个进程侦听同一系统上的不同端口。负载均衡器根据来自各个守护进程的一些负载反馈来决定哪个进程获得下一个连接
设计#2最复杂。设计#3很简单,但涉及到额外的硬件,无论设计如何,我都需要这些硬件,因为我将在几台机器上运行它,并且无论如何都需要一个负载均衡器。设计#1有闪电群问题,但我猜闪电群对8个进程来说不是什么大问题,但当客户端不断连接和断开连接时(这应该是罕见的,因为这是一个彗星服务器),它就变成了一个大问题。
在我看来,#2是复杂的,需要2个额外的系统调用,因为在主& &;每个接收的从属进程。有这样的头顶比有这样的问题更好吗?如果我有8个进程唤醒并执行一个accept,如果我使用设计#1,我可能会看到8个accept调用吗?
我的设计选择的利弊是什么?你有什么建议吗?
如果不是进程,而是线程,我会选择选项2。无论如何,对于进程来说,这看起来很昂贵,所以我们要在1和3之间选择。
如果可能以某种方式估计预期负载,我更喜欢1。你能不能给休眠进程设定一个上限,比如预先分叉的进程?您需要多快才能接受新的连接?
所以,如果你要走汤姆·邓森的路,把一大群牲口快速带过红河到堪萨斯州,你可能需要选择第三条路。
如果您的目标是制作一个非常大规模,高吞吐量的HTTP守护进程,第一条、第二条和第三条都不合适。如果你想获得可伸缩性,你最好使用1对m或m对n的多线程模型,就像nginx/lighttp那样。
事实上,如果您希望程序在一秒钟内处理少于一百个连接,那么#1, #2和#3可能没有任何明显的区别。
但是,如果您将来可能通过将进程切换到线程来扩展您的程序,我将选择#2,因为它可以很容易地集成到1对m或m对n处理模型中。