如何让Express+TypeORM应用崩溃后自动重启或避免崩溃?
Express+TypeORM应用崩溃自动重启与防崩溃方案
问题背景
我是新手😊,当前我的Express+TypeORM应用崩溃后,开发环境需修改代码并保存重启,生产环境需执行pm2 restart appname-here手动重启。希望实现应用崩溃后自动重启,或通过代码避免应用崩溃。
我的代码如下:
index.ts
AppDataSource.initialize().then(async () => { const app = express(); app.use(express.json()); app.use(cookieParser()); app.use(cors({ credentials: true, origin: ["ABOVE YOUR PAYGRADE"] })); routes(app); app.listen(8000, () => { console.log('listening to port 8000'); }); }).catch(error => process.exit());
data-source.ts
export const AppDataSource = new DataSource({ type: "mysql", host: "ABOVE YOUR PAYGRADE", username: "ABOVE YOUR PAYGRADE", password: "ABOVE YOUR PAYGRADE", database: "ABOVE YOUR PAYGRADE", synchronize: true, logging: false, migrations: [], entities: ["src/entity/*.ts"], subscribers: [] });
一、实现崩溃后自动重启
开发环境
使用nodemon工具,它能监听文件变化,同时在应用崩溃时自动重启:
- 安装依赖:
npm install nodemon --save-dev - 在
package.json中添加开发脚本:
"scripts": { "dev": "nodemon index.ts" }
- 启动开发服务:
npm run dev,之后代码修改或应用崩溃都会自动重启。
生产环境
利用PM2自带的自动重启机制,无需手动执行重启命令:
- 直接启动时配置自动重启:
pm2 start index.ts --name appname-here --autorestart true --max_restarts 10
--autorestart true:开启崩溃自动重启--max_restarts 10:限制最大重启次数,避免无限循环
- 更推荐用PM2配置文件(
ecosystem.config.js)管理:
module.exports = { apps: [{ name: 'appname-here', script: 'index.ts', autorestart: true, max_restarts: 10, restart_delay: 1000, // 崩溃后延迟1秒重启 env: { NODE_ENV: 'production' } }] };
执行pm2 start ecosystem.config.js启动应用,PM2会自动处理崩溃重启。
二、代码层面避免应用崩溃
1. 添加Express全局错误处理中间件
在所有路由之后添加全局错误捕获中间件,拦截路由中未处理的错误,避免应用崩溃:
import { Request, Response, NextFunction } from 'express'; // 放在routes(app)之后 app.use((err: Error, req: Request, res: Response, next: NextFunction) => { console.error('全局错误:', err); res.status(500).json({ message: '服务器内部错误' }); });
2. 优化数据库连接错误处理
原代码中数据库连接失败直接退出进程,改为重试机制,避免单次连接失败导致应用崩溃:
const initializeDataSource = async () => { try { await AppDataSource.initialize(); console.log('数据库连接成功'); startExpressApp(); } catch (error) { console.error('数据库连接失败,5秒后重试:', error); setTimeout(initializeDataSource, 5000); } }; const startExpressApp = async () => { const app = express(); app.use(express.json()); app.use(cookieParser()); app.use(cors({ credentials: true, origin: ["ABOVE YOUR PAYGRADE"] })); routes(app); // 全局错误处理中间件 app.use((err: Error, req: Request, res: Response, next: NextFunction) => { console.error('全局错误:', err); res.status(500).json({ message: '服务器内部错误' }); }); app.listen(8000, () => { console.log('listening to port 8000'); }); }; initializeDataSource();
3. 捕获异步路由错误
异步路由未捕获的错误会导致崩溃,用express-async-handler简化捕获:
- 安装依赖:
npm install express-async-handler - 在路由中使用:
import asyncHandler from 'express-async-handler'; app.get('/api/example', asyncHandler(async (req, res) => { // 异步操作的错误会自动传递到全局错误处理中间件 const data = await AppDataSource.getRepository(YourEntity).find(); res.json(data); }));
4. 捕获全局未处理异常
在代码开头添加全局异常捕获,处理未被拦截的同步/异步错误,优雅退出后由PM2或nodemon重启:
process.on('uncaughtException', async (error) => { console.error('未捕获异常:', error); // 清理数据库连接 if (AppDataSource.isInitialized) { await AppDataSource.destroy(); } process.exit(1); }); process.on('unhandledRejection', async (reason, promise) => { console.error('未处理的Promise拒绝:', reason, promise); if (AppDataSource.isInitialized) { await AppDataSource.destroy(); } process.exit(1); });
内容的提问来源于stack exchange,提问作者chantellebradley
相关产品推荐
相关产品推荐

