Nodejs在不同Linux操作系统上的奇怪表现

Nodejs在不同Linux操作系统上的奇怪表现

在不同VPS上压力测试的时候发现的,都是用的CENTOS

有的CPU还没有跑满,TCP就没响应了,等一段时间后,又恢复正常了 而且是开始响应很快,后来越来越慢 具体来说就是连续服务一定数量的请求NODE就“假死”了 (VPS虚拟技术是XEN的,并发越大,假死的越快----更快达到了上述的请求数量)

有的则服务很稳定,不管服务多少数量的请求均没有假死的情况发生,响应速度也一致稳定,但是并发上不去(超过200系统就报错) 虚拟技术好像是OPENVZ的,不确定…

搜索了一下,提高了Linux的文件数限制之类的,但是没有效果;CENTOS好像限制了什么东西


3 回复

Node.js 在不同 Linux 操作系统上的奇怪表现

在使用 Node.js 进行开发时,尤其是在不同的 VPS 环境中部署应用,可能会遇到一些令人困惑的问题。这些问题往往与操作系统的配置、内核参数以及虚拟化技术有关。以下是一些可能的原因和解决方案。

背景信息

我们发现,在不同 VPS 上进行压力测试时,Node.js 应用的表现有所不同。这些 VPS 都运行的是 CentOS 操作系统,但所使用的虚拟化技术不同(Xen 和 OpenVZ)。

问题描述

  1. Xen 虚拟化技术

    • 现象:某些 VPS 使用 Xen 虚拟化技术,当 CPU 尚未达到满负荷时,TCP 连接就会失去响应。过一段时间后,连接会恢复正常。
    • 具体表现:开始时响应速度较快,但随着请求的数量增加,Node.js 应用逐渐变得迟钝,最终“假死”。
    • 可能原因:可能是由于 Xen 的资源分配机制导致的,特别是在高并发情况下,资源分配不均衡。
  2. OpenVZ 虚拟化技术

    • 现象:另一些 VPS 使用 OpenVZ 虚拟化技术,虽然服务非常稳定,不会出现假死情况,但并发请求的数量受到限制(超过 200 请求时,系统报错)。
    • 具体表现:无论请求的数量如何,响应速度始终保持稳定,但在高并发情况下,系统会出现错误。
    • 可能原因:可能是 OpenVZ 对于文件描述符和资源限制有更严格的限制。

解决方案

  1. 调整系统参数

    • 文件描述符限制
      # 编辑 /etc/security/limits.conf 文件
      * soft nofile 65536
      * hard nofile 65536
      
    • 内核参数调整
      # 编辑 /etc/sysctl.conf 文件
      fs.file-max = 100000
      net.core.somaxconn = 65535
      net.ipv4.tcp_max_syn_backlog = 65535
      
  2. 优化 Node.js 应用

    • 使用集群模式
      const cluster = require('cluster');
      const os = require('os');
      
      if (cluster.isMaster) {
        const numCPUs = os.cpus().length;
        for (let i = 0; i < numCPUs; i++) {
          cluster.fork();
        }
      } else {
        // Worker process
        require('./app');
      }
      
    • 使用高性能 HTTP 服务器
      const http = require('http');
      const cluster = require('cluster');
      const os = require('os');
      
      if (cluster.isMaster) {
        const numCPUs = os.cpus().length;
      
        for (let i = 0; i < numCPUs; i++) {
          cluster.fork();
        }
      
        cluster.on('exit', (worker, code, signal) => {
          console.log(`Worker ${worker.process.pid} died`);
        });
      } else {
        http.createServer((req, res) => {
          res.writeHead(200);
          res.end('Hello World\n');
        }).listen(8000);
      }
      

通过以上方法,可以显著提高 Node.js 应用在不同 Linux 操作系统上的性能和稳定性。


已解决:

/etc/sysctl.conf 文件添加如下参数增加系统限制

net.ipv4.netfilter.ip_conntrack_max = 3276800 net.ipv4.tcp_tw_recycle = 0 net.ipv4.tcp_tw_reuse = 0 net.ipv4.tcp_orphan_retries = 1 net.ipv4.tcp_fin_timeout = 25 net.ipv4.tcp_max_orphans = 8192 net.ipv4.ip_local_port_range = 32768 61000

换算过来差不多是每小时请求超过1W的应用需要修改上述参数(注OVZ虚拟机可能某些参数会没有权限)

这个问题描述了在不同的Linux操作系统(如CentOS)和不同的虚拟化技术(如Xen和OpenVZ)下,Node.js应用的表现差异。问题的核心在于Node.js在某些环境中容易出现“假死”的现象,而在其他环境中则表现得非常稳定。

分析原因

  1. 文件描述符限制:尽管你已经提高了系统的文件描述符限制,但Node.js的应用可能还在某些方面受限。
  2. 进程调度和资源分配:不同的虚拟化技术对CPU、内存和其他资源的调度方式不同,这可能影响到Node.js应用的性能和稳定性。
  3. 网络配置:TCP连接处理可能因为网络配置的不同而受到影响,比如TCP backlog大小等。

解决方案

  1. 调整系统参数

    • 确保调整了ulimit设置,特别是文件描述符数量(nofile),以及进程的最大数量(nproc)。
    • 可以尝试调整TCP相关参数,例如增加/proc/sys/net/core/somaxconn的值来增加TCP连接队列的长度。
  2. 优化Node.js应用

    • 使用cluster模块来利用多核处理器。
    const cluster = require('cluster');
    const os = require('os');
    
    if (cluster.isMaster) {
        // 主进程创建多个子进程
        for (let i = 0; i < os.cpus().length; i++) {
            cluster.fork();
        }
    } else {
        // 子进程
        require('./app');
    }
    
  3. 检查依赖库

    • 检查是否有依赖的库或模块可能存在bug,导致性能下降。
  4. 监控和调试

    • 使用监控工具(如Prometheus + Grafana)来监控系统负载和Node.js应用的性能指标。
    • 调试时使用Node.js的内置工具或第三方库(如process.memoryUsage())。
  5. 调整虚拟机设置

    • 如果可能,尝试调整虚拟机的资源配置,如CPU核心数、内存大小等。

通过上述方法,你可以更好地理解和解决Node.js在不同Linux操作系统上的表现差异问题。

回到顶部