Skip to content

极致省内存的node服务器架构

发布日期:2023-07-04

在性能极低的2核1g个人服务器上,实现 nodejs 服务自动化部署


前言

我的目前使用的阿里云服务器使用centos8系统,2核1g内存,也要600块一年,性能捉襟见肘,但是用来学习linux操作非常合适。经过我的一系列操作发现,当系统内存占用过高时,系统会出现异常io,读操作占满进程,表现为服务器假死,ssh无法链接,只能重启服务器或等待3小时-1天不等的时间自动恢复,但这种症状会不定时发作,原因未明。

为了解决这个问题,我google了很久,尝试删除阿里云监控进程,也给阿里云提了工单,但仍然不管用。我的推测是阿里云的监控程序扫盘占用大量io导致服务器假死。于是我另辟蹊径,尝试降低系统内存占用,事实证明在低内存占用的情况下,服务假死的现象没有再发生了。

其中服务器技术栈为koa + sequelize + sqlite;前端技术栈为vite + vue3

nodejs服务器

服务器框架采用了轻量化的koa,很多东西都需要手动配置,对于学习服务器开发来说非常合适,对于性能来说也是非常高效。我曾经使用过nestjs框架,大而全面,模仿spring的代码风格,但感觉比较臃肿,最终没有采用,选择了从零开始开发的koa服务。

nodejs进程采用pm2进行管理。最开始时使用ts-node直接执行ts代码,发现内存占用过大;于是编译为js后再执行,内存占用明显改善;ts-node保留为开发服务使用。后来发现通过pm2调用npm命令启动服务的内存占用很大,于是改用bash脚本启动服务,内存占用又节省了很多。

服务器的自动化部署

最开始选择方案时想到了dockor,但docker占用内存太大,连安装都成问题。我们公司内部自动化部署使用的是jenkins,是一个使用java语言开发的自动化发布工具,也是通过打包docker镜像的方式实现自动化部署,因此也不适用。容器化方案需要高内存占用,对于1g内存来说压力太大了,因此开始考虑非容器化的方案。

最终的自动化部署方案,是开启一个简单的koa部署服务,监听gitee的webhook,对主服务进行重新部署。

数据库

最初使用的mysql作为数据库,就遇到了前言描述的服务器假死现象,不得不考虑更轻量的数据库方案。既然启动一个数据库服务内存占用过太,那就采用无服务的方式,最终选择sqlite作为数据库,应付个人开发的数据量已经足够。

部署前端页面

前端页面是用nginx服务驱动的,需要考虑的是怎样实现自动化部署。我最开始的想法是和服务器一样,监听gitee的webhook来进行自动化打包,但是构建代码的时候,又遇到了前言描述的服务器假死问题,推测是构建时占用内存过大,真是举步维艰。最终采用了本地构建的方式,使用ssh2-sftp-client库通过sftp上传到指定的nginx目录,来进行前端页面的部署。

内存优化结果

使用 ps aux | head -1;ps aux |grep -v PID |sort -rn -k +4 | head -10 查看占用内存前10的应用,第一位是主服务,第二位是pm2服务,第三位是部署服务;共占用17.6%的内存,对于1g内存来说还有很富裕的空间。

内存优化结果

Power by vitepress