☰
Midway 服务器启动失败排查指南:从进程检查、错误日志到环境问题的系统化定位
2026/10/10 8:17:26 网站建设 项目流程
  • 后端
  • 微服务
  • 云原生

【免费下载链接】midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈

项目地址:https://gitcode.com/gh_mirrors/mi/midway
点击查看免费下载

应用在服务器上启动失败,是 Node.js 全栈开发者最常遇到的运维场景之一。本文基于 Midway 官方运维文档《服务器启动失败排查》整理成文,系统梳理从"快速定位代码问题"到"逐项排查环境问题"的完整排查链路,并结合仓库源码与部署文档,深入讲解common-error.log日志体系、dist构建产物校验、启动用户权限以及端口冲突等高频故障的根因与解法。读完本文,你将掌握一套在任何 Linux 服务器上都能直接落地的 Midway 启动失败排查方法论。

快速定位代码问题:从进程和日志入手

大多数情况下,我们所说的"启动失败"指的都是服务器环境下的启动失败,下面以 Linux 环境为例展开。逻辑错误、编译错误、配置错误、环境问题,都有可能导致项目无法启动,而排查的核心思路是:先确认现象,再查看日志,最后定位根因。

第 1 步:检查进程是否存在

使用ps aux | grep node检查进程是否存在,并核对进程数量是否正确:

$ ps aux | grep node
  • 如果没有任何 node 进程,说明应用根本没有启动起来,可能是在启动早期就崩溃了;
  • 如果有进程但数量不对(比如 cluster 模式配置了 4 个实例却只起了 1 个),需要检查进程管理工具的配置与系统资源限制;
  • 如果进程存在但服务无法访问,则问题可能出在端口监听、防火墙或反向代理配置上。

第 2 步:查看错误日志

打开项目的日志目录,查看common-error.log文件的内容,根据最新的堆栈信息来排查原因。关于日志根目录的详细说明,可以参考 日志文档中的"配置日志根目录"一节。

common-error.log是 Midway 的统一错误日志:所有由 Midway 创建出来的日志对象,都会将错误重复打印一份到该文件中,因此它是启动失败排查时最值得优先查看的文件。

第 3 步:查看启动控制台日志

对于使用 pm2 等进程管理器托管的应用,可以查看启动时的控制台输出,例如:

$ pm2 logs

在 pm2 下还可以只查看某个应用的输出:

$ pm2 logs test_app

大多数问题都会在日志中发现,请尽可能养成登录机器查看日志的习惯,这是开发者必备的技能。

可能的环境问题:逐项排查

除了代码本身的问题之外,环境问题也可能导致启动失败。这类问题排查起来往往更困难,通常和系统、权限、环境变量、启动参数、网络环境甚至内核本身有关系。下面列举几种常见情况。

1、文件不完整或不是最新

Midway 是 TypeScript 编写的框架,部署到服务器时运行的是编译后的 JavaScript 产物,因此"构建流程没走完"或"文件上传不完整"是最常见的启动失败诱因。

首先,确保项目在部署前执行过以下完整的本地验证流程:

  1. 使用npm run dev或者类似命令本地启动并运行成功;
  2. 使用npm run build已将 TS 文件编译为 JS 文件,在根目录生成出dist目录;
  3. 使用npm run start在本地使用编译后的 JS 文件执行成功。

然后,检查服务器上的文件与目录结构是否完整:

  1. node_modules目录是否存在(服务器上只安装生产依赖时尤其容易遗漏关键依赖);
  2. dist目录以及其中的 JS 文件是否存在,或者为最新(务必确认上传的是最新构建产物,而不是旧包)。

从部署文档可以确认,服务器部署后 Midway只会加载构建后的dist目录,而本地开发加载的是src目录,两者的baseDir完全不同(详见启动和部署文档)。因此dist缺失或过期,必然导致服务器启动失败。部署时服务器运行必须包含package.json、bootstrap.js、dist、node_modules这些文件或目录。

2、启动用户的权限问题

生产环境一般会使用一个普通账户来执行应用(比如admin账户),而不是使用sudo去部署。这样做的目的是限制应用权限、降低安全风险。排查时关注两点:

  1. 检查用户是否拥有创建目录、启动 node 的权限;
  2. 检查项目的服务端日志目录是否有写入的权限。

为什么日志目录权限如此关键?从 日志文档 可知,Midway 在本地开发和服务器部署时的日志输出位置不同:

  • 本地的日志根目录为${app.appDir}/logs/项目名;
  • 服务器的日志根目录为用户目录${process.env.HOME}/logs/项目名(Linux/Mac)以及${process.env.USERPROFILE}/logs/项目名(Windows)下,例如/home/admin/logs/example-app。

也就是说,应用启动时需要在当前用户主目录下创建logs/项目名目录并持续写入日志文件。如果该用户没有主目录写入权限,日志系统初始化就会失败,进而导致整个应用无法启动。在 @midwayjs/web 的默认配置 中可以看到,应用日志文件名被设置为midway-web.log,错误日志统一写入logs/${appInfo.pkg.name}/common-error.log,这些文件的创建都依赖启动用户的目录写权限。

3、启动端口冲突

如果你在服务器上启动了多个 Node.js 项目,而它们使用了相同的端口,那么后启动的项目就会抛出端口重复使用的错误(典型如EADDRINUSE)。

排查方法:

# 查看指定端口被哪个进程占用 $ lsof -i :7001 # 或者 $ netstat -tlnp | grep 7001

找到占用进程后,要么调整本项目配置的监听端口,要么释放被占用的端口。Midway 默认的 HTTP 端口由使用的 Web 框架决定(如 Koa 默认7001),可通过对应框架的配置项修改端口。

深入理解 common-error.log 与 Midway 日志体系

启动失败排查的核心抓手是日志,因此有必要深入理解 Midway 的日志体系。根据 日志文档,Midway 会在日志根目录创建以下默认文件:

文件说明
midway-core.log框架、组件打印信息的日志,对应coreLogger
midway-app.log应用打印信息的日志,对应appLogger;在@midwayjs/web中,该文件是midway-web.log
common-error.log所有错误的日志(所有 Midway 创建出来的日志,都会将错误重复打印一份到该文件中)

其中common-error.log是整个排查流程中价值最高的文件,因为它聚合了框架、组件、应用以及请求链路所有日志对象的错误输出,启动阶段的异常堆栈几乎都会出现在这里。

从 web 框架日志实现 的源码注释可以进一步看到,日志对象还支持concentrateError配置项来控制错误日志的写入策略,可选值为:

  • duplicate:错误同时输出到自身日志文件与common-error.log(默认行为);
  • redirect:错误只重定向到common-error.log;
  • ignore:忽略错误日志的聚合写入。

排查启动失败时,若common-error.log中没有任何内容,也可以反推出应用可能在日志系统初始化之前就崩溃了,此时应优先查看控制台输出或进程启动早期的 stderr。

从部署流程反推启动失败根因

很多服务器启动失败,本质上是部署流程不完整。理解 启动和部署文档 中的部署流程,可以帮助你更快地判断问题属于哪一环节:

整个部署分为几个部分:由于 Midway 是 TypeScript 编写,比传统 JavaScript 代码增加了一个构建步骤。典型的服务器构建流程如下:

$ npm install # 安装开发期依赖 $ npm run build # 构建项目,生成 dist 目录 $ npm prune --production # 移除开发依赖

构建完成后,项目结构大致为:

. ├── src ├── dist # Midway 构建产物目录 ├── node_modules # Node.js 依赖包目录 ├── test ├── bootstrap.js # 部署启动文件 ├── package.json └── tsconfig.json

服务器上运行时,通过bootstrap.js入口启动(Midway 默认已内置@midwayjs/bootstrap模块):

const { Bootstrap } = require('@midwayjs/bootstrap'); Bootstrap.run();

线上使用 pm2 启动的典型命令为(详见 pm2 文档):

$ NODE_ENV=production pm2 start ./bootstrap.js --name midway_app -i 4

其中-i 4表示以 cluster 模式启动 4 个实例。部署前后环境有三点明显差异,这些差异往往就是启动失败的来源:

  1. Node 环境变化:服务器直接使用 node 启动项目,不再依赖ts-node读取*.ts文件;
  2. 加载目录变化:服务器只加载构建后的dist目录(baseDir指向dist),本地开发加载src目录;
  3. 环境变量变化:服务器一般设置NODE_ENV=production,许多库会在该环境下启用缓存、不同的报错处理等行为;
  4. 日志文件位置变化:服务器环境下日志输出到不受项目更新影响的固定目录(如/home/admin/logs),而不是项目的logs目录。

所以,当你在服务器上遇到启动失败,可以按部署链路逐段自查:本地npm run dev是否成功 →npm run build是否生成最新dist→npm run start(即NODE_ENV=production node bootstrap.js)本地是否成功 → 服务器上文件和目录是否完整 → 启动用户是否有写权限 → 端口是否被占用。任何一环断裂,都可能导致启动失败。

排查启动失败的完整清单

将上述内容整理为一份可直接对照执行的清单:

  1. 进程层面:ps aux | grep node确认进程存在且数量正确;
  2. 日志层面:查看common-error.log最新堆栈(位置参考 配置日志根目录),再查看 pm2 等工具的控制台日志(pm2 logs);
  3. 构建产物:确认npm run build已在本地生成最新dist,服务器上的dist、node_modules完整且为最新;
  4. 权限层面:确认启动用户(如admin)有创建目录、启动 node、向${HOME}/logs/项目名写入日志的权限;
  5. 端口层面:lsof -i :端口或netstat -tlnp确认没有端口冲突;
  6. 环境差异:确认NODE_ENV、baseDir(srcvsdist)、日志根目录等与本地开发的差异已正确适配。

小结

服务器启动失败排查的核心方法论可以概括为"先日志、后环境":先通过进程状态和common-error.log快速定位代码层问题,再针对构建产物完整性、启动用户权限、端口冲突三大高发环境问题逐项排查。结合 日志体系文档 对日志根目录和默认日志文件的理解,以及 部署流程文档 对构建产物与运行环境差异的把握,绝大多数启动失败都能在几分钟内定位根因。养成登录机器查看日志的习惯,是每一位后端与全栈开发者的必备技能。

  • 后端
  • 微服务
  • 云原生

【免费下载链接】midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈

项目地址:https://gitcode.com/gh_mirrors/mi/midway
点击查看免费下载

相关推荐

上一篇:Prometheus Node.js 客户端项目推荐:监控你的应用性能的终极指南
下一篇:OpenCensus-Java核心功能解析:打造高可用微服务监控系统

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询