我正在运行一个相当大规模的Node.js 0.8.8应用,使用 Cluster 在一台有超线程(32个逻辑核心)的16核处理器上运行着16个工作进程。我们发现自从升级到 Linux 3.2.0 内核后(从 2.6.32),来自外部请求在工作子进程间的负载均衡似乎严重倾向于其中的5个或更多进程,而其他11个进程几乎不做任何工作。这可能更高效地提高吞吐量,但增加了请求延迟,并且对我们不是最优选择,因为其中许多是长期存在的 WebSocket 连接,它们可以同时开始进行工作。
所有子进程都在套接字上接受连接(使用 epoll),虽然这个问题在 Node 0.9 中有一个修复方法 (https://github.com/bnoordhuis/libuv/commit/be2a2176ce25d6a4190b10acd1de9fd53f7a6275),但在我们的测试中那个修复方法似乎没有帮助。是否有人知道内核调整参数或构建选项可以帮助解决问题?或者我们最好回到 2.6 内核或使用不同的方法跨工作进程进行负载平衡?
我们将其归结为一个简单的 HTTP Siege 测试,但需要注意的是,这是在一个有超线程(24个逻辑核心)的12核处理器上以 12 个工作进程接受套接字,与我们生产环境的 16 核不同。
在 Debian Squeeze 上使用 Node 0.9.3,在裸机上运行着 2.6.32 内核的 HTTP Siege:
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