我正在运行一个相当大规模的Node.js 0.8.8应用程序,使用具有超线程(所以32个逻辑核心)的16处理器盒上的16个工作进程的集群。 我们发现,自从转向Linux 3.2.0内核(从2.6.32版本)以来,工作进程之间的传入请求的平衡似乎被大大加权到5个左右的进程,而其他11个进程并没有做太多的工作。 这对于吞吐量可能更有效,但似乎增加了请求延迟,对我们来说并不是最优的,因为其中很多都是长寿的websocket连接,可以同时开始工作。
subprocess都接受套接字(使用epoll),而这个问题有一个修复节点0.9(https://github.com/bnoordhuis/libuv/commit/be2a2176ce25d6a4190b10acd1de9fd53f7a6275),这个修复似乎没有帮助我们的testing。 有没有人知道内核调优参数或构build选项可以帮助,还是我们最好的回到2.6内核或跨工作stream程负载平衡使用不同的方法?
我们把它简化成一个简单的HTTP Siegetesting,不过要注意的是,这是在一个带有超线程(12个核心)的12核处理器上运行的12个处理器(有24个逻辑核心),有12个工作进程在套接字上接受,而我们的16在生产过程中。
在Debian上使用节点0.9.3的HTTP Siege在裸机上使用2.6.32内核:
reqs pid 146 2818 139 2820 211 2821 306 2823 129 2825 166 2827 138 2829 134 2831 227 2833 134 2835 129 2837 138 2838
除了3.2.0内核,其他所有内容都是一样的
reqs pid 99 3207 186 3209 42 3210 131 3212 34 3214 53 3216 39 3218 54 3220 33 3222 931 3224 345 3226 312 3228
不要依靠操作系统的套接字多接受平衡负载跨Web服务器进程。
Linux内核的行为在版本和版本上有所不同,我们看到3.2内核的一个特别不平衡的行为,在后来的版本中似乎更加平衡。 例如3.6。
我们是在这样的假设下工作的:应该有办法让Linux像循环一样做这件事情,但是这有很多问题,包括:
您可以在我们用来与优秀的Node.js团队对应的github问题上详细看到我们的测试,从这里开始: https : //github.com/joyent/node/issues/3241#issuecomment-11145233
那个对话以Node.js小组结束,表示他们正在认真考虑在Cluster中实现显式循环,并且开始一个问题: https : //github.com/joyent/node/issues/4435和Trello团队(这就是我们)进入我们的后备计划,即使用本地HAProxy进程在每台服务器计算机上跨16个端口进行代理,并在每个端口上运行2个工作进程的群集实例(用于在接受级别上进行快速故障转移在进程崩溃或挂起的情况下)。 这个计划运行的非常好,大大减少了请求延迟和平均延迟。
这里还有很多需要说的,我没有采取邮寄Linux内核邮件列表的步骤,因为不清楚这是一个真正的Xen还是Linux内核问题,或者真的只是一个错误的多个接受的期望我们的行为。
我很乐意看到多位接受专家的回答,但是我们回到我们可以使用我们更好理解的组件来构建的东西。 如果有人发表更好的答案,我会很高兴接受而不是我的。