跳到主要内容

云引擎 Node.js 运行环境

信息

这篇文档是针对 Node.js 运行环境的深入介绍,如希望快速地开始使用云引擎,请查看 快速开始部署云引擎应用。

所有 Node.js 项目都必须在根目录包含一个 package.json 和启动脚本(如没有在控制台或 leanengine.yaml 内指定,请确保 package.json 内的 scripts.start 存在)才会被云引擎正确识别,云引擎也会从中读取项目对于环境的需求:

package.json
{
"name": "node-js-getting-started",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js -- "
},
"dependencies": {
"leancloud-storage": "^3.11.0",
"leanengine": "^3.3.2"
},
"devDependencies": {
"nodemon": "^1.18.7"
},
"engines": {
"node": "16.x"
}
}

如果你希望创建一个新的项目,推荐从我们的 Node.js 示例项目 开始。

启动命令​

云引擎默认使用 npm start 来启动项目,你可以在 package.json 中修改 scripts.start 来使用不同的程序入口或向 node 添加额外的参数。

package.json
{
"scripts": {
"start": "node server.js"
}
}
备注

在使用 命令行工具 本地调试时,lean up 会优先使用 npm run dev 来启动项目。

配置 Node.js 版本​

在 package.json 的 engines.node 字段可以指定 Node.js 版本:

package.json
{
"engines": {
"node": "16.x"
}
}

你还可以设置为 * 表示总是使用最新(current)版本。

备注
对于新创建的应用,如未设置 Node.js 版本,云引擎会默认使用最新的稳定(LTS)版本。在 2021-09-02 之前创建的分组因兼容考虑会默认使用 `0.12` 版本。

配置包管理器​

云引擎目前支持以下包管理器:

云引擎会按照以下条件使用包管理器:

包管理器条件版本
pnpm存在合法能被解析的 pnpm-lock.yaml
lockfileVersion: '6.0' 或更高8
lockfileVersion: 5.3 或更高7
其他6
Yarn 1存在 yarn.lock1
Yarn 2+不默认支持,需通过 Corepack 启用2+
npm其他情况使用 Node.js 默认提供的 npm

实验性 Corepack 支持​

由于 Corepack 还是实验性特性,云引擎不能保证对 Corepack 的支持是稳定的

通过给分组设置 ENABLE_EXPERIMENTAL_COREPACK 环境变量为任意非空字符串来启用实验性 Corepack 支持。

云引擎会通过调用 Corepack 读取 package.json 里的 packageManager 字段来自动识别、使用用户指定的包管理器,这也是目前唯一一种使用 Yarn 2+ 的方式。

假设有以下 package.json:

package.json
{
"name": "example",
"packageManager": "yarn@4.0.2"
}

此时云引擎会自动调用 corepack prepare --activate 并识别包管理器为 Yarn 2+。

参考:Corepack

默认命令​

云引擎默认运行的脚本会随着包管理器的变化而变化,如使用了 pnpm, npm ci 会变成 pnpm install --frozen-lockfile。

云引擎只有在没有指定 installDevDependencies 为 true 且构建脚本为空(没有手动指定,package.json 里的 scripts.build 不存在)时才会省略 devDependencies 的安装。

阶段包管理器条件命令
installnpmNode.js 10 以上且存在 package-lock.json 或 npm-shrinkwrap.jsonnpm ci
npm install 或 npm install --omit=dev
pnpmpnpm install --frozen-lockfile 或 pnpm install --frozen-lockfile --prod
Yarn 1yarn install 或 yarn install --production
Yarn 2+yarn install
备注

请注意 Yarn 1 只会使用 yarn.lock 内解析的 URL 下载依赖且不会遵循用户设置的源,请选择合适的源,否则可能会增加构建时间。

安装依赖(package.json)​

云引擎会自动安装 package.json 中的依赖:

package.json
{
"dependencies": {
"leancloud-storage": "^3.11.0",
"leanengine": "^3.3.2"
},
"devDependencies": {
"nodemon": "^1.18.7"
}
}

在安装依赖的过程中,云引擎会正常触发 NPM 的生命周期脚本(Life Cycle Scripts),如 postinstall、prepare 等。

因为云引擎会在云端安装依赖,所以命令行工具默认也不会上传 node_modules 目录;如果使用 Git 部署,也建议将 node_modules 目录添加到 .gitignore 中,使其不加入版本控制。

备注

云引擎会上传 .yarn 文件夹,所以如果启用了 Yarn 2+ 的 PnP(Plug'n'Play)但不想使用 Zero-installs,请将 .yarn/cache 加入到 .gitignore 和 .leanignore 中

自定义构建过程​

除了默认的构建过程和运行命令外,开发者还可以在 leanengine.yaml 中进一步地调整运行命令(run)、依赖安装命令(install)和构建命令(build),覆盖默认的行为:

leanengine.yaml
run: echo 'run another command'
install:
- {use: 'default'}
- echo 'install additional dependencies here'
build:
- echo 'overwrite default build command here'

详细的说明见 Reference: leanengine.yaml,下面是一些具体的例子:

为子项目安装依赖​

leanengine.yaml
install:
- use: default
- require:
- ./frontend/package.json
- ./frontend/package-lock.json
- cd frontend && npm ci
build:
- npm run build
- cd frontend && run build

这里我们在保留默认行为的同时,额外为 frontend 目录下的项目安装了依赖、运行了构建命令。

系统级依赖​

在云引擎的线上环境中,开发者可以在 leanengine.yaml 中定义额外的系统级依赖:

leanengine.yaml
systemDependencies:
- imagemagick

支持的完整列表见 Reference: leanengine.yaml。

构建日志​

默认情况下构建过程中产生的日志不会显示到控制台,只有构建失败时,最后一个步骤的日志才会被显示在控制台上。

如需打印完整的构建日志以便调试,可以在部署时勾选「打印构建日志」或命令行工具添加参数 --options 'printBuildLogs=true'。

健康检查​

云引擎目前主要为 Web 应用优化,应用在启动后需要在环境变量 LEANCLOUD_APP_PORT 中指定的端口上提供 HTTP 服务,注意需要监听在 0.0.0.0 地址(所有接口)上,而不是一些框架默认的 127.0.0.1。

在应用部署时,云引擎的管理程序会每隔一秒去检查应用是否启动成功,如果超过启动时间限制(默认 30 秒)仍未启动成功,即认为启动失败,部署会中止。在之后的运行过程中,也会有定期的健康检查来确保应用正常运行,如果健康检查失败,云引擎管理程序会自动重启你的应用。

健康检查会通过 HTTP 检查应用的首页(/),如果返回 HTTP 2xx 的响应,就视作成功。

点击展开健康检查与云引擎 SDK 的关联

云引擎还会尝试检查由 SDK 处理的 /__engine/1/ping,如果 SDK 接入正确,便不再要求首页(/)返回 HTTP 2xx。

如果 云服务控制台 > 云引擎 > 管理部署 > 你的分组 > 设置 > 云函数模式 设置为「开启」或 leanengine.yaml 中 functionsMode 设置为 strict,云引擎会检查 SDK 是否被正确地接入,否则会视作启动失败。

点击展开自定义启动时长(startupTimeout)

启动时间限制默认为 30 秒,可设置范围为 15–120 秒,如需延长或缩短,可以在 leanengine.yaml 文件中设置:

leanengine.yaml
startupTimeout: 60

云端环境​

绑定自定义域名​

云引擎需要设置域名才能访问。在 云服务控制台 > 云引擎 > 管理部署 > 你的分组 > 设置 > 访问域名 处可以绑定域名。

如果你绑定的域名以 stg- 开头(如 stg-api.example.com),会自动关联到预备环境。

对于测试阶段的应用,我们提供了共享域名,你可以自定义共享域名的前缀部分。

负载均衡和加速节点​

所有对云引擎的 HTTP 或 HTTPS 请求都会经过负载均衡,负载均衡组件会处理 HTTPS 加密、重定向到 HTTPS、对响应进行压缩等一般性工作,因此云引擎上的程序不需要自己实现这些功能。同时负载均衡带来的一些限制,在云引擎程序内进行修改也无法越过,如:

  • /.well-known/acme-challenge/ 开头的路径被用于自动管理证书,不会转发到云引擎程序。
  • 请求头(URL 和 header)每行最大 8K,总计最大 64K。
  • 请求体积(上传文件体积)最大 100M。
  • 连接或等待响应的超时时间为 60 秒。

获取客户端 IP 等信息​

云引擎的负载均衡会在 HTTP header 中传递一些有关原始请求的信息:

  • X-Real-IP: 请求的来源 IP。
  • X-Forwarded-Proto: 请求的来源协议(http 或 https)。
  • Forwarded: RFC 7239 规定的用于传递代理信息的头,包含 IP 和 协议。

在 Express 中:

app.get("/", function (req, res) {
console.log(req.headers["x-real-ip"]);
res.send(req.headers["x-real-ip"]);
});

重定向到 HTTPS​

在绑定云引擎自定义域名时,可以选择「强制 HTTPS」,勾选后负载均衡组件会将 HTTP 的请求重定向到 HTTPS 的同一路径。

环境变量​

云引擎平台默认提供下列环境变量供应用使用:

变量名说明
LEANCLOUD_APP_ID当前应用的 App ID。
LEANCLOUD_APP_KEY当前应用的 App Key。
LEANCLOUD_APP_MASTER_KEY当前应用的 Master Key。
LEANCLOUD_APP_ENV当前的应用环境:开发环境没有该环境变量,或值为 development(通过命令行工具启动)。预备环境值为 stage。生产环境值为 production。
LEANCLOUD_APP_PORT当前应用开放给外网的端口,只有监听此端口,用户才可以访问到你的服务。
LEANCLOUD_API_SERVER访问存储服务时使用的地址。该值会因为所在数据中心等原因导致不一样,所以使用 REST API 请求存储服务或其他云服务时请使用此环境变量的值。
LEANCLOUD_APP_GROUP云引擎实例所在的组。当使用云引擎组管理功能时,该值为组的名称。
LEANCLOUD_REGION云引擎服务所在区域,值为 CN 或 US,分别表示国内版和国际版。
LEANCLOUD_VERSION_TAG云引擎实例部署的版本号。

旧版云引擎使用的以 LC_ 开头的环境变量(如 LC_APP_ID)已经被弃用。为了保证代码兼容性,LC_ 变量在一段时间内依然有效,但未来可能会完全失效。为了避免报错,建议使用 LEANCLOUD_ 变量来替换。

你还可以在控制台上设置自定义的环境变量来存储配置信息。

日志​

备注

关于如何在控制台上查看日志,以及访问日志等更多内容,请看 云引擎平台功能 § 查看日志。

云引擎会收集应用打印到标准输出(stdout)和标准错误输出(stderr)的日志:

console.log("hello"); // stdout
console.error("some error"); // stderr
备注

日志单行最大 4096 个字符,多余部分会被丢弃;日志收集速率最大 600 行每分钟,多余的部分会也被丢弃。

时区​

云引擎使用 UTC+0 时区。

文件系统​

你可以向 /home/leanengine 或 /tmp 目录写入临时文件,最多不能超过 1 GB。

警告

云引擎每次部署都会产生一个新的容器,即使不部署系统偶尔也会进行一些自动调度,这意味着你 不能将本地文件系统当作持久的存储,只能用作临时存储。

如果你写入的文件体积较大,建议在使用后自动删除他们,否则如果占用磁盘空间超过 1 GB,继续写入文件可能会收到类似 Disk quota exceeded 的错误,这种情况下你可以重新部署一下,这样文件就会被清空了。

出入口 IP 地址​

如果开发者希望在第三方服务平台(如微信开放平台)上配置 IP 白名单而需要获取云引擎的入口或出口 IP 地址,请进入 云服务控制台 > 云引擎 > 管理部署 > 云引擎分组 > 设置 > 出入口 IP 来自助查询。

我们会尽可能减少出入口 IP 的变化频率,但 IP 突然变换的可能性仍然存在。因此在遇到与出入口 IP 相关的问题,我们建议先进入控制台来核实一下 IP 列表是否有变化。

如需保持入口 IP 不变,建议为云引擎绑定独立 IP。

疑难问题​

Node.js 项目的 devDependencies 没有安装?​

云引擎会在部署时用 npm ci 为你安装项目依赖,包括 devDependencies。 不过,如果项目的 Node.js 版本小于 10,或者项目目录下没有 lockfile,则会使用 npm install --production 安装依赖,相应地,devDependencies 中列出的依赖不会安装,可参考 默认命令。 如需安装 devDependencies,请在项目的 leanengine.yaml 中指定 installDevDependencies: true。

npm ERR! peer dep missing 错误怎么办?​

部署时出现类似错误:

npm ERR! peer dep missing: graphql@^0.10.0 || ^0.11.0, required by express-graphql@0.6.11

说明有一部分 peer dependency 没有安装成功,因为 Node.js 版本小于 10 时,线上只会安装 dependencies 部分的依赖,所以请确保 dependencies 部分依赖所需要的所有依赖也都列在了 dependencies 部分(而不是 devDependencies)。

你可以在本地删除 node_modules,然后用 npm install --production 重新安装依赖来重现这个问题。

或者,你也可以考虑将项目升级到 Node.js 10 以上的版本。

路由超时设置​

因为 Node.js 的异步调用容易因运行时错误或编码疏忽中断,为了减少在这种情况下对服务器内存的占用,也为了客户端能够更早地收到错误提示,所以需要添加这个设置,一旦发生超时,服务端会返回一个 HTTP 错误码给客户端。

使用 Express 框架实现自定义路由的时候,请求默认的超时时间为 15 秒,该值可以在 app.js 中进行调整:

// 设置默认超时时间
app.use(timeout("15s"));