Nodejs在高并发下的性能优化,各位有哪些好的建议吗?
Nodejs在高并发下的性能优化,各位有哪些好的建议吗?
公司业务需要用 node 转发微信消息给其他后端服务器,每次推送 20W 模板消息, node 会收到 TEMPLATESENDJOBFINISH 的消息回复
一开始和这个问题的情况类似,逻辑很简单,就接受消息转发消息,也是用 request 发送消息,并发量一大后面的请求处理时间就很长,导致经常 5s 内无法响应微信服务器进而报警。后来查了半天发现 node 默认线程池只有 4 个线程,以及 socket 池最多 5 个 socket 连接,于是就把这两个给调大了,竟然有用,好的时候都能在 5s 内处理完,但还是发生了一两次超时的情况,微信报警都是 1W+ 的无返回。
目前看来大部分时候能处理完,说明 node 本身应该是能撑住这么多并发。但那一两次报警都有 1W+,显然也不正常,而那一两次报警时,接受的请求和数量都没什么不同,求教大家可能的情况?
大家如果有其他 node 性能优化或者高并发的建议,也欢迎讨论
主要逻辑是转发消息,但还是稍稍有些判断的, node 帮助挡掉 TEMPLATESENDJOBFINISH 的消息,其他时候根据用户 groupid 转发给不同的后端
直接 return success 再用 setTimeout 或者队列转发到后端呀,后端根据需要用客服接口发送消息就可以。
对于 TEMPLATESENDJOBFINISH 是直接 return success 的,对于用户发来的消息,会根据情况转发给不同的后端,现在的问题是后端发送大量模板消息,微信回复的 TEMPLATESENDJOBFINISH 消息就都到 node 这来, node 有两次有 1W+ 的消息没在 5s 内处理完,感觉很诡异,要说扛不住,那应该每次都扛住了,但现在大部分时候扛住了就这么两次处理超时。。
那就再加大点 thread pool 和 max sockets 😁
加到多少呢。。现在是 4 核的机器, PM2 开了 4 个进程 64 个线程
socket pool 加到多大了?
7000 。。这个数字我看别人调几 W ,感觉机器比较一般就调了 7000 ,我也不知道调多少比较好
nodejs 最大的优点不是可以 scale up 用多台服务器均衡 request
用 DB 或其他的作一个队列
1 、调 v8 引擎参数;
2 、最大 socket 数在 0.12 版本之前默认是 5 ,之后都是正无穷,所以直接改成正无穷,或者升级版本;
3 、调系统限制参数,各种 limit ;
4 、开多个服务来扩展;
5 、运行时通过 v8-profiler ,查看内存和 CPU 状态,查出瓶颈;
6 、考虑上个消息队列。
收到消息记录到内存或文件立即返回,再用其他进程处理消息,在 node 前面加个 nginx ,分发到不同的 node 节点上。
最好的办法?当然是不用 node 。。。。。
同意 11L 。
如果没有特别实时性的要求,可以尝试 redis 等做 message queue
感觉应该直接压到队列里面啊。
针对Node.js在高并发下的性能优化,以下是一些专业建议:
-
异步非阻塞I/O:
Node.js的异步非阻塞特性使其在处理高并发时具有天然优势。通过异步I/O,Node.js可以在等待I/O操作(如数据库查询或文件读取)完成时继续处理其他请求。
const http = require('http'); const server = http.createServer((req, res) => { setTimeout(() => { res.writeHead(200); res.end('Hello World\n'); }, 100); }); server.listen(8000, () => { console.log('Server is running at http://localhost:8000/'); });
-
使用Cluster模块:
利用Node.js的Cluster模块,可以充分利用多核CPU的处理能力,通过创建多个子进程(workers)来提高并发处理能力。
const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { for (let i = 0; i < numCPUs; i++) { cluster.fork(); } } else { http.createServer((req, res) => { res.writeHead(200); res.end('Hello World\n'); }).listen(8000); }
-
优化代码和中间件:
尽量减少阻塞代码,避免全局变量,使用高效的数据结构。同时,在使用Express等框架时,应审查并减少中间件的使用,确保只加载必要的中间件。
-
使用缓存:
对于频繁访问的数据,可以使用内存缓存(如Node-cache)或分布式缓存(如Redis)来减少数据库访问次数。
-
监控与调优:
使用性能分析工具(如Node.js内置的profiler)和APM工具(如New Relic)来监控应用性能,并识别瓶颈进行调优。