You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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工具,它能监听文件变化,同时在应用崩溃时自动重启:

  1. 安装依赖:npm install nodemon --save-dev
  2. 在package.json中添加开发脚本:
"scripts": {
  "dev": "nodemon index.ts"
}
  1. 启动开发服务:npm run dev,之后代码修改或应用崩溃都会自动重启。

生产环境

利用PM2自带的自动重启机制,无需手动执行重启命令:

  1. 直接启动时配置自动重启:
    pm2 start index.ts --name appname-here --autorestart true --max_restarts 10
  • --autorestart true:开启崩溃自动重启
  • --max_restarts 10:限制最大重启次数,避免无限循环
  1. 更推荐用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简化捕获:

  1. 安装依赖:npm install express-async-handler
  2. 在路由中使用:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:03:11