不少团队写 Web 后端时,第一个想到的是 Node.js。上手快,生态大,前后端还能用同一门语言。真正麻烦的是代码写完以后,怎么在线上稳定地跑起来。阿里云的承载方式不少,选对了,后面的运维会省很多力。下面结合两个实际场景,说说 Node 项目在阿里云上怎么落地。

动手前先想清楚三个问题
选型之前,先问自己三件事:流量稳不稳定,团队里有没有专人管运维,业务对冷启动敏不敏感。三个答案不同,选的东西也会不一样。
- 流量比较稳,服务要保持长连接或常驻进程:用云服务器 ECS,配合 PM2 或 systemd 守护进程,进程挂了能自动拉起。
- 流量忽高忽低,请求之间基本独立:可以考虑函数计算 FC 或 Serverless 应用引擎 SAE,按请求量计费,适合波动大的场景。
- 服务数量多,需要统一编排和发布:容器服务 ACK 更合适,发布流程可以交给 Helm 管理。
案例一:小团队电商后台,ECS 跑 Node
一个做垂直电商的小团队,后台接口全部用 Express 写成,日均请求量大概几十万次。最开始所有服务都跑在一台 ECS 上,前面挂 Nginx 做反向代理,更新代码就是在服务器上 git pull。业务涨起来以后,问题一个个冒出来:每次发版都会断几秒,单机一挂,整个后台就打不开了。
后来他们分三步改。第一步,把 Node 进程交给 PM2 管理,开启 cluster 模式,让多核 CPU 都用上。第二步,在前面加一层阿里云负载均衡 SLB,后端挂两台 ECS,发版时逐台摘下来更新再放回去。第三步,把会话和缓存迁到 Redis。原来会话存在进程内存里,多实例之间无法共享。改完之后,发版不再影响用户,单台出问题时流量会自动切到另一台。
这个案例里还有几处细节值得参考。ECS 的安全组只开放必要端口,Node 服务监听内网地址,外网流量统一经 SLB 进入。数据库用 RDS,别和应用装在同一台机器上,否则应用的资源波动会直接牵连数据库。日志接入日志服务 SLS,出问题时可以按请求去追。
案例二:图片处理接口,用函数计算压低成本
另一个例子来自一家内容社区。他们有个图片压缩加水印的接口,调用量很不均匀。白天高峰时每秒几十次请求,夜里几乎没有流量。原来用 ECS 撑着,全天都要付费,资源大部分时间闲着。
他们把这段 Node 代码改成函数计算 FC 的处理函数。入口接收图片地址,用 sharp 完成处理,结果写入对象存储 OSS,再把访问地址返回。函数按调用次数和执行时长计费,夜里没人调用,基本不产生费用。这个方案上线前最需要盯的是冷启动。他们给函数设置了预留实例,保证白天高峰时响应稳定;同时把依赖尽量精简,缩短初始化时间。
上传部分的代码大致如下,用的是官方 SDK ali-oss:
const OSS = require('ali-oss');
const client = new OSS({
region: process.env.OSS_REGION,
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
bucket: process.env.OSS_BUCKET
});
async function uploadImage(localPath, objectName) {
const result = await client.put(objectName, localPath);
return result.url;
}
密钥全部通过环境变量注入,不要写进代码仓库。更稳妥的做法是给函数或 ECS 绑定 RAM 角色,让它们通过临时凭证访问 OSS,长期密钥暴露的风险就小了很多。
上线前逐项确认
不管选哪种方案,下面几项最好在上线前过一遍。
- Node 版本选 LTS,并在 package.json 的 engines 字段里写明,避免本地和线上版本对不上。
- 依赖版本锁定,提交 package-lock.json。线上装出来的依赖要和本地一致,否则问题很难复现。
- 密钥和配置走环境变量或配置中心,代码里不留明文。
- 单独提供健康检查接口,负载均衡或容器平台靠它判断实例是否可用。
- 接入云监控,对 CPU、内存、事件循环延迟和错误率设置告警。
- 进程要处理 SIGTERM 信号,退出前把未完成的请求处理完,否则发版时可能丢数据。
写在最后
阿里云上跑 Node 没有标准答案。流量稳、需要精细控制的业务,ECS 加 SLB 是成熟可靠的做法。流量起伏明显、按需付费更划算的场景,函数计算能减轻不少运维负担。先看清自己业务的特征,再决定放在哪里跑。选定之后,把日志、监控和发布流程补齐,服务才算真正跑稳。