温馨提示×

如何在Linux中实现Node.js负载均衡

小樊
44
2025-12-06 13:01:48
栏目: 云计算

在 Linux 上实现 Node.js 负载均衡

一、方案总览与选型

  • 反向代理层:使用 NginxHAProxy 将请求分发到多个 Node.js 实例,支持轮询、权重、健康检查、限流与压缩,适合生产环境。
  • 进程内扩展:使用 Node.js 内置 cluster 模块 启动多个工作进程,充分利用多核 CPU,适合单机多核优化。
  • 应用内代理:用 http-proxy / http-proxy-middleware 在 Node.js 中自写简单负载均衡,便于与业务集成,但生产级能力与稳定性通常不如前两类。
  • 容器化编排:使用 Docker Compose / Kubernetes 管理多实例与滚动更新,结合 K8s Service 或 Ingress 做服务层负载均衡。

二、使用 Nginx 作为反向代理

  • 安装与启用
    • Ubuntu/Debian
      • 安装:sudo apt update && sudo apt install nginx
      • 检查:sudo nginx -t
      • 生效:sudo systemctl reload nginx
    • CentOS/RHEL
      • 安装:sudo yum install -y epel-release && sudo yum install -y nginx
      • 启动与开机自启:sudo systemctl start nginx && sudo systemctl enable nginx
  • 基本配置示例(/etc/nginx/sites-available/default 或 /etc/nginx/nginx.conf 的 http 块内)
    • 定义上游与反向代理
      http {
        upstream node_app {
          server 127.0.0.1:3000;
          server 127.0.0.1:3001;
          server 127.0.0.1:3002;
        }
      
        server {
          listen 80;
          server_name your_domain.com;
      
          location / {
            proxy_pass http://node_app;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
      
            # WebSocket 支持
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'Upgrade';
            proxy_cache_bypass $http_upgrade;
          }
        }
      }
      
    • 要点
      • 多实例端口如 3000/3001/3002 对应你的 Node 进程。
      • 按需开启 HTTPS/TLS(可使用 Let’s Encrypt)。

三、使用 HAProxy 作为负载均衡器

  • 安装
    • Ubuntu/Debian:sudo apt update && sudo apt install haproxy
  • 配置示例(/etc/haproxy/haproxy.cfg)
    global
      log /dev/log local0
      log /dev/log local1 notice
      daemon
    
    defaults
      log global
      mode http
      option httplog
      option dontlognull
      timeout connect 5000ms
      timeout client 50000ms
      timeout server 50000ms
    
    frontend http_front
      bind *:80
      default_backend http_back
    
    backend http_back
      balance roundrobin
      server node1 127.0.0.1:3000 check
      server node2 127.0.0.1:3001 check
      server node3 127.0.0.1:3002 check
    
  • 生效与验证
    • 检查:sudo haproxy -c -f /etc/haproxy/haproxy.cfg
    • 重启:sudo systemctl restart haproxy
  • 说明
    • 算法可用 roundrobin/leastconn 等;开启 check 做健康检查。

四、进程内与容器化实践

  • Node.js Cluster 模式(单机多核)
    const cluster = require('cluster');
    const http = require('http');
    const numCPUs = require('os').cpus().length;
    
    if (cluster.isMaster) {
      console.log(`Master ${process.pid} is running`);
      for (let i = 0; i < numCPUs; i++) cluster.fork();
      cluster.on('exit', (worker) => console.log(`worker ${worker.process.pid} died`));
    } else {
      http.createServer((req, res) => {
        res.writeHead(200);
        res.end(`Hello from worker ${process.pid}\n`);
      }).listen(8000);
    }
    
    • 适合提升单机吞吐;与反向代理结合可获得更完整的生产特性(静态资源、压缩、缓存、限流等)。
  • 应用内简单代理(Node.js + http-proxy)
    const http = require('http');
    const httpProxy = require('http-proxy');
    const servers = ['http://127.0.0.1:3000','http://127.0.0.1:3001','http://127.0.0.1:3002'];
    let idx = 0;
    const proxy = httpProxy.createProxyServer({});
    http.createServer((req,res)=>{
      const target = servers[idx = (idx+1)%servers.length];
      proxy.web(req,res,{target});
    }).listen(80);
    
    • 便于原型与集成,生产环境建议使用 Nginx/HAProxy
  • Docker Compose 多实例
    • docker-compose.yml
      version: '3'
      services:
        node_app:
          build: .
          ports:
            - "3000"
          deploy:
            replicas: 3
            update_config: { parallelism: 1, delay: 10s }
            restart_policy: { condition: on-failure }
      
    • 启动:docker-compose up -d;在 K8s 中可用 Service/Ingress 做负载均衡。

五、健康检查、高可用与运维要点

  • 健康检查与故障隔离
    • Nginx:在 upstream 中使用 max_fails/fail_timeoutserver 127.0.0.1:3000 max_fails=3 fail_timeout=30s 等策略。
    • HAProxy:使用 check 参数与更细粒度的 http-check 规则,自动摘除异常实例。
  • 进程与实例管理
    • 使用 PM2 管理多实例与零停机重启:pm2 start app.js -i max(按 CPU 核数),pm2 save && pm2 startup
  • 网络与安全
    • 开放防火墙端口(Ubuntu/Debian 常见为 ufw allow 80,443;CentOS/RHEL 使用 firewall-cmd 放行 http/https)。
    • 启用 HTTPS/TLS(如 Let’s Encrypt),并在代理层设置 X-Real-IP / X-Forwarded-For / X-Forwarded-Proto 以便后端获取真实客户端信息。
    • 静态资源建议由 Nginx 直接服务,动态请求反向代理到 Node.js。

0