关于Node服务端项目崩溃原因分析
问题分析
这里主要介绍本人调试node服务端内存的过程,其中有些其实都是些简单的错误,主要是想记录一下整个过程。方便自己反思和总结。
首先这个问题,存在已久本人深感抱歉,这次的通过多核的x86服务器进行对比分析,目前发现了问题的原因。
先说一下la服务器的现象,node服务运行过久,会有一两个单个cpu爆满,导致项目死机,延迟无法访问。随着客户人数增大,这个问题更加频繁。
测试过程
这次分析,显示用一个x86的服务器,搭建了服务端的环境,并在node环境中安装了alinode插件(node性能分析工具),然后通过电脑打开了了15个客户端请求,然后再通过脚本工具,进行压力测试。然后我在性能测试平台上发现了一个问题,对于不同请求node服务确实可以实现多进程处理,但是对于同一个ip过来的请求,服务端无法把访问的流量均摊到每个node服务器(这里说一下node服务端的设计,因为node是单线程的,所以为了提高node服务端的处理能力,node服务有个负载均衡的能力,在node启动的时候,会根据服务器cpu的核数,启动相应的node进程,然后均摊处理外部请求)。这里就发现在在现在的服务器上这个功能存在问题。
测试结果
这个图是在x86下面,用现在的服务端环境进行测试的结果,对于外面压力测试只有一个进程在执行。下面是通过htop和alinode性能监测平台观察的
解决办法
目前能够解决的办法有以下几点:
1,解决服务框架里面egg多进程负载均衡的问题
框架内部封装的代码,目前通过升级了同一个大版本下的依赖包,暂未能解决问题
2,通过第三方插件进行负载均衡,例如PM2
通过手写的入口文件,通过pm2启动项目,暂时还存在报错,报错暂时还未解决
3,升级系统框架,新版的框架是通过koa2开发的,可以便捷的通过第三方插件启动实现多进程的负载均衡效果
以下是新框架的压测测试结果图:多核cpu能实现负载均衡
下面是在x86上的测试情况:
4,是通过自己手写egg入口文件,实现项目的启动
第一步在项目根目录,新建入口文件server.js,新增内容如下:
const egg = require('egg'); const workers = Number(process.argv[2] || require('os').cpus().length); egg.startCluster({ workers, port: 7003, baseDir: __dirname, });
然后可以通过命令以下命令启动项目:
NODE_ENV=production nohup node server.js &
我们把它封装到packjson里面,如下
这样就可以通过
npm run nohup
启动项目了
当然,单入口文件实现成功,自然可以通过第三方进程守护程序启动入口文件实现进程守护,比如pm2,具体不在细述。
原因分析
启动的egg-script插件,启动后的进程之间通信存在问题。
对比参数发现,目前框架启动的时候,多了一个 --sticky
然后发现去掉这个参数,启动服务进程间通信就恢复正常了。
–sticky这个参数是使用socket.io必须增加的参数,如果加了这个参数,正式环境必须配合redis才能实现进程间通信。
我在压测的过程中还发现node项目存在内存泄露,详细分析过程见下一篇文章。