NodeJS到底适用什么场景

NodeJS到底适用什么场景

公司的业务都是基于HTTP协议Java开发的,也就是说使用Nginx+Tomcat这种组合,今日看到NodeJS不错,就对照其中一个业务(对应一个Servlet)做了一个NodeJS版本,测试结果让我非常失望。

公司业务原始架构: Nginx + Tomcat + Redis + Mysql

NodeJS版架构: NodeJS + Redis (默认数据已经载入Redis,不需要再读数据库) 使用了generic-pool作为Redis的连接池

测试结果 Java版每秒处理峰值3.6K req#/sec左右 (说明:ab -n 1000 -c 100 ,直接对一台Tomcat压) NodeJS版每秒只能处理1.6K req#/sec

这让我情何以堪啊。说真的,这种测试结果让我很疑惑,近日还听说网易用这玩意做了一个游戏引擎,这货的性能真的如传说中那么NB吗?


10 回复

NodeJS到底适用什么场景

引言

公司目前的业务主要基于HTTP协议,使用的是Nginx + Tomcat的架构。为了探索新技术的可能性,我尝试将其中一个业务模块从Java迁移到Node.js上,并进行了性能测试。测试结果显示,Node.js版的性能不如预期,每秒处理请求的数量仅为Java版的一半。这引发了我对Node.js适用场景的一些疑问。

公司原始架构

  • Nginx: 用于负载均衡和反向代理。
  • Tomcat: 处理HTTP请求,提供后端服务。
  • Redis: 用于缓存数据,减少数据库访问。
  • MySQL: 存储持久化数据。

尝试Node.js版架构

  • Node.js: 用于处理HTTP请求。
  • Redis: 用于缓存数据,减少数据库访问。
  • generic-pool: 用于管理Redis连接池。

测试结果

  • Java版: 每秒处理峰值为3.6K req#/sec。
  • Node.js版: 每秒处理峰值为1.6K req#/sec。

Node.js适用场景

尽管这次测试结果并不理想,但Node.js在某些特定场景下依然具有明显的优势:

  1. 实时应用

    • WebSocket: Node.js非常适合构建实时应用,如聊天室、在线游戏等。它能够高效地处理大量并发连接。
    • 示例代码:
      const http = require('http');
      const WebSocket = require('ws');
      
      const server = http.createServer((req, res) => {
        res.writeHead(200);
        res.end('Hello World');
      });
      
      const wss = new WebSocket.Server({ server });
      
      wss.on('connection', (ws) => {
        ws.on('message', (message) => {
          console.log(`Received: ${message}`);
          ws.send(`Pong: ${message}`);
        });
      });
      
      server.listen(3000, () => {
        console.log('Server started on port 3000');
      });
      
  2. 微服务架构

    • 轻量级API: Node.js可以轻松构建微服务,每个服务专注于单一功能,易于扩展和维护。
    • 示例代码:
      const express = require('express');
      const app = express();
      
      app.get('/api/data', (req, res) => {
        res.json({ message: 'Hello from microservice!' });
      });
      
      app.listen(3001, () => {
        console.log('Microservice listening on port 3001');
      });
      
  3. I/O密集型应用

    • 非阻塞I/O: Node.js的事件驱动模型使得它可以高效处理I/O密集型任务,如文件读写、网络通信等。
    • 示例代码:
      const fs = require('fs');
      
      fs.readFile('./data.txt', (err, data) => {
        if (err) throw err;
        console.log(data.toString());
      });
      
      console.log('Reading file...');
      

总结

尽管本次测试结果不尽人意,但Node.js在实时应用、微服务架构以及I/O密集型应用方面仍然具有独特的优势。对于特定类型的业务场景,Node.js依然是一个值得考虑的选择。


莫非有阻塞?

性能真是挺关心的. 虽然 Node 不是靠语言性能出彩的… 楼主贴更多细节看看吧… 总共几个核, 开了几个进程, 逻辑性处理有多少… 实在不行看看代码

是不是业务逻辑很复杂 可以看看这篇文章~里面讲了node适用及不适用的场合http://nodeguide.com/convincing_the_boss.html

node是单进程,你要测试性能,要用cluster多开几个进程来跑  这样比较结构才有比较意义

Cluster是个好东西,我用了之后性能大幅提高,NodeJS已经可以跑到4.5K req#/sec啦。

nodejs跑helloword 跟nginx不相上下

你可以测试下jetty,jetty的并发比tomcat要强一点 我测试的结果是

 jetty7.5          2302.57rps  
tomcat7.0.32   2062.93rps
测试环境 linux-2.6.18 contos5.4 ab -n 10000 -c 250

lz应该看看node的适用场景,对于pomelo可以先看看文档,性能调优也是一步一步做的。 https://github.com/NetEase/pomelo/wiki/pomelo性能参考

Node.js 主要适用于以下几种场景:

  1. 实时应用:如聊天室、协作工具等,Node.js 的事件驱动模型非常适合处理 I/O 密集型任务。
  2. API 服务:构建 RESTful API 服务器,处理大量并发请求。
  3. 微服务架构:轻量级的服务可以快速响应请求,并且易于扩展。

针对您提到的性能问题,可以考虑以下几个方面进行优化:

  • 异步编程:确保 Node.js 代码充分利用其异步特性。
  • 负载均衡:多实例部署可以提升整体性能。
  • 性能调优:调整 Node.js 应用的配置参数,例如堆内存大小。

以下是一个简单的 Node.js 示例代码,用于处理 HTTP 请求:

const http = require('http');
const redis = require('ioredis'); // 使用 ioredis 作为 Redis 客户端

// 创建 Redis 连接池
const pool = new genericPool.createPool({
    create: () => redis.createClient(),
    destroy: (client) => client.disconnect()
}, {
    max: 5,
    min: 0,
    acquireTimeoutMillis: 30000,
    idleTimeoutMillis: 30000,
});

const server = http.createServer(async (req, res) => {
    try {
        const client = await pool.acquire();
        const data = await client.get('key');
        pool.release(client);

        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ message: 'Data fetched from Redis', data }));
    } catch (error) {
        console.error(error);
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('Internal Server Error');
    }
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

这段代码展示了如何使用 generic-pool 管理 Redis 连接,并处理 HTTP 请求。通过这种方式,您可以更好地利用 Node.js 的非阻塞特性来提高性能。

回到顶部