Bolt-js Slack应用Jenkins+PM2部署EADDRINUSE问题咨询
Slack Bolt-js应用PM2集群重载问题排查与解决
问题1:bolt-js是否与AWS EC2部署不兼容?
完全兼容。你遇到的端口占用和重载失败问题,是部署配置冲突导致的,和bolt-js、EC2本身的兼容性无关,大量生产环境的Slack应用都是基于bolt-js部署在EC2上的。
问题2:集群从1切换至0失败的原因?
核心原因有两个:
- 生产环境误用nodemon:从日志里的
[nodemon] app crashed可以看出,你的npm start是用nodemon启动应用的。nodemon是开发环境的文件监听工具,它的崩溃重试逻辑(等待文件变化)会和PM2的集群重载逻辑冲突。当重载时新进程因端口占用启动失败,nodemon会直接进入“等待文件变化”的阻塞状态,不会自动重试,导致PM2无法完成集群切换。 - PM2配置参数错误:你的
exec_mode写的是cluster_mode,但PM2的正确参数是cluster;另外用npm作为启动脚本,相当于在PM2的集群进程里又套了一层npm子进程,PM2无法直接控制Node.js进程的端口共享和优雅关闭,加重了端口占用的概率。
从1切换到0时卡住,本质是nodemon的阻塞逻辑:旧进程关闭后,新进程启动触发端口占用错误,nodemon直接挂起等待文件修改,PM2无法感知这个状态,导致切换流程中断。
可行解决办法
1. 修正PM2配置文件(核心)
修改ecosystem.config.js,直接启动Node.js进程,去掉nodemon和npm的中间层:
module.exports = { apps: [{ name: 'project-name', cwd: './project-path', script: 'app.js', // 直接指向应用入口文件 instances: 0, // 根据CPU核心数自动启动进程 exec_mode: 'cluster', // PM2正确的集群模式参数 env: { NODE_ENV: 'production' // 显式指定生产环境,避免启动开发工具 } }] };
如果你的package.json里start脚本是node app.js,也可以用script: 'node', args: 'app.js',效果一致。
2. 添加应用优雅关闭逻辑
在app.js里添加信号监听,确保PM2发送停止信号时,bolt-js的HTTPReceiver能优雅释放端口:
const { App } = require('@slack/bolt'); const app = new App({ // 你的bolt-js配置 }); // 处理PM2的SIGINT信号,优雅关闭应用 process.on('SIGINT', async () => { console.log('Received SIGINT, shutting down gracefully'); await app.stop(); // 停止HTTPReceiver,释放端口 process.exit(0); }); // 启动应用 (async () => { await app.start(process.env.PORT || 3000); console.log('⚡️ Bolt app is running!'); })();
3. 调整CI/CD的重载命令
确保CI/CD里执行的是:
pm2 reload ecosystem.config.js --env production
避免直接用pm2 reload <appname>,确保加载最新配置。
4. 彻底移除生产环境的nodemon
检查package.json,确保生产依赖里没有nodemon,拆分脚本区分开发和生产环境:
{ "scripts": { "start": "node app.js", "dev": "nodemon app.js" } }
开发时用npm run dev,生产环境用npm start(或直接用PM2启动app.js)。
内容的提问来源于stack exchange,提问作者SEEWON
相关产品推荐
相关产品推荐

