Operation and Maintenance Guide

12003

When developing locally, we use egg-bin dev to start the service, but this should not be used when deploying the application. This is because egg-bin dev performs many operations tailored for local development, while the production environment requires a simpler and more stable approach. This chapter mainly explains how to deploy your application.

Generally, the process from source code to running consists of two steps: building and deploying, achieving one build, multiple deployments.

Build

The JavaScript language itself does not require compilation; the build process mainly involves downloading dependencies. If you are using TypeScript or Babel to support ES6 and above features, then a build is necessary.

When installing dependencies, it is common to specify NODE_ENV=production or use npm install --production to install only core dependencies. This is because development dependencies can be large and are unnecessary in the production environment, which may lead to issues.

$ cd baseDir
$ npm install --production
$ tar -zcvf ../release.tgz .

After building, package it into a tgz file. During deployment, simply unzip and start it.

Adding a build step allows for true one build, multiple deployments. Theoretically, when the code has not changed, there is no need to rebuild, and the original package can be deployed, bringing numerous benefits:

  • Differences between the build environment and the running environment avoid polluting the running environment.
  • Shortens release time and facilitates rollback; simply restarting the original package suffices.

Deployment

The server needs to have Node.js pre-installed, and the framework supports Node versions >= 14.20.0.

The framework has a built-in egg-cluster to start the Master process, which is stable and does not require process management modules like pm2.

The framework also provides egg-scripts to support running and stopping in production.

First, include the egg-scripts module in dependencies:

$ npm i egg-scripts --save

Add npm scripts in package.json:

{
  "scripts": {
    "start": "egg-scripts start --daemon",
    "stop": "egg-scripts stop"
  }
}

Now, you can start and stop the application using npm start and npm stop.

Note: The support for egg-scripts on Windows is limited; see #22 for details.

Start Command

$ egg-scripts start --port=7001 --daemon --title=egg-server-showcase

The example supports the following parameters:

  • --port=7001: Port number, defaults to reading process.env.PORT; if not provided, it uses the built-in port 7001.
  • --daemon: Enables background mode, no need for nohup; it is recommended to run in the foreground when using Docker.
  • --env=prod: Running environment, defaults to reading process.env.EGG_SERVER_ENV; if not provided, it uses the built-in prod.
  • --workers=2: Number of workers, defaults to creating an app worker equal to the number of CPU cores, utilizing CPU resources.
  • --title=egg-server-showcase: Facilitates grepping when using ps for processes; if not set, defaults to egg-server-${appname}.
  • --framework=yadan: When using a custom framework, configure egg.framework in package.json or specify this parameter.
  • --ignore-stderr: Ignores startup errors.
  • --https.key: Path to the HTTPS key.
  • --https.cert: Path to the HTTPS certificate.

All options of egg-cluster are supported for passthrough, such as --port, etc.

For more parameters, see the egg-scripts and egg-cluster documentation.

Note: The default for --workers is set by process.env.EGG_WORKERS or os.cpus().length; in Docker, os.cpus().length may be greater than the number of cores, and a large value may cause failures, so --workers should be set manually; see #1431 for details.

Startup Configuration

Startup configurations can be specified in config.{env}.js.

// config/config.default.js

exports.cluster = {
  listen: {
    port: 7001,
    hostname: '127.0.0.1', // It is not recommended to set this to '0.0.0.0' as it may pose external connection risks; please use with caution.
    // path: '/var/run/egg.sock',
  },
};

path, port, and hostname refer to the parameters in server.listen. The port passed to egg-scripts and egg.startCluster takes precedence over this configuration.

Stop Command

$ egg-scripts stop [--title=egg-server]

This command kills the master process and gracefully exits the worker and agent.

Supported parameters:

  • --title=egg-server: Kills the specified Egg application; if not set, it terminates all Egg applications.

You can also find the master process using ps -eo "pid,command" | grep -- "--title=egg-server" and kill it without needing kill -9.

Monitoring

We also need to monitor the service for performance, memory leak analysis, troubleshooting, etc.

Commonly used tools in the industry include:

Node.js Performance Platform (Alinode)

Note: The Node.js Performance Platform (Alinode) currently only supports macOS and Linux, and does not support Windows.

The Node.js Performance Platform provides a comprehensive solution for performance monitoring, security alerts, troubleshooting, and performance optimization for all Node.js applications. It offers a complete toolchain and services to help developers quickly identify and locate online issues.

Installing Runtime

Alinode Runtime can directly replace Node.js Runtime; refer to the documentation for the corresponding version.

For global installation, refer to the documentation.

Sometimes, when deploying multiple projects simultaneously and expecting multiple versions to coexist, you can install the Runtime in the current project:

$ npm i nodeinstall -g
$ nodeinstall --install-alinode ^3

nodeinstall will install the corresponding version of alinode in the project's node_modules directory.

Note: The operating system of the packaging machine and the online system must be consistent; otherwise, the corresponding Runtime may not run properly.

Installation and Configuration

We provide egg-alinode for quick integration without the need to install additional persistent services like agenthub.

Install dependencies:

$ npm i egg-alinode --save

Enable the plugin:

// config/plugin.js
exports.alinode = {
  enable: true,
  package: 'egg-alinode',
};

Configuration:

// config/config.default.js
exports.alinode = {
  // Get the corresponding access parameters from the `Node.js Performance Platform`
  appid: '<YOUR_APPID>',
  secret: '<YOUR_SECRET>',
};

Starting the Application

The start command configured in npm scripts does not need to be changed; it can be executed via egg-scripts.

The start command must use npm start, as executing npm scripts will add the node_module/.bin directory to the PATH, thus prioritizing the Node version executed in the current project.

After starting, you will see the master log containing the following content:

$ [master] node version v8.9.4
$ [master] alinode version v3.8.4
$ [Tue Aug 06 2019 15:54:25 GMT+0800 (China Standard Time)] Connecting to wss://agentserver.node.aliyun.com:8080...
$ [Tue Aug 06 2019 15:54:26 GMT+0800 (China Standard Time)] agent register ok.

Where agent register ok. indicates that the configured egg-alinode has successfully connected to the Node.js Performance Platform server.

Accessing the Console

Console address: https://node.console.aliyun.com