Yireo - Developer training

Open main menu

Vue Storefront 1 Fundamentals On-Demand course

Using PM2

Duration: 16:42 | Last Modified 13 August 2021

This is a lesson preview of our Yireo On-Demand training on Vue Storefront 1 Fundamentals

This is a preview lesson only

Note that this is a preview lesson. When accessing this lesson as part of the full training, there are a couple of benefits: The materials are available via the Yireo Courseware portal and can be presented as a slideshow, progress can be monitored, additional resources will be available. And obviously, all lessons - instead of just the preview lessons - will be available to you.

Get full access to the Vue Storefront 1 Fundamentals training

Student notes

Using PM2

As soon as VSF1 runs in production, the tool PM2 becomes vital. This lesson dives into the common usage of PM2, but also into some less known facts or modifications.

Using PM2

  • PM2 process manager
    • Guarantees uptime of Node processes
  • Configured through ecosystem.json
  • Used by yarn start
    • pm2 start ecosystem.json
  • Usage
    • node_modules/.bin/pm2
    • yarn pm2
    • Beware of the global pm2 command (if it is there)

First of all, PM2 is a process manager that tries to make sure that Node processes, run though PM2, are always up and reachable. PM2 uses a configuration file ecosystem.json which we will take a look at in a bit. Both the PWA and the API are run in production using PM2. Each uses a command yarn start which simply calls upon pm2 start to start all relevant services, that are defined in the ecosystem.json file.

Any command that starts with yarn pm2 is passed on to the local PM2 instance node_modules/.bin/pm2. While you could also install PM2 globally on your server (like in /usr/local/bin/pm2), this is less recommended because there might be crucial differences between versions. Simply use yarn pm2 instead.

PM2 commands

  • yarn pm2 start
    • Start processes
  • yarn pm2 status
    • Show the status of all Node processes
  • yarn pm2 stop all
    • Stop all Node processes
  • yarn pm2 kill
    • Kill all Node processes
  • yarn pm2 delete
    • Remove Node processes from listing
  • yarn pm2 logs
    • Show active logs

Various commands help you to manage the processes via PM2. Once the processes are started with start, you can monitor their status using status: You'll not only see the process name and its status (which in general should be online) but also CPU usage and memory consumption. This becomes relevant once we discuss the ecosystem.json file.

Processes can be stopped, killed and deleted. Once a process is stopped, it can be started without referring to the ecosystem.json file. If no processes are defined yet, the start command needs to be accompanied by the JSON file: yarn pm2 start ecosystem.json.

Logging is possible locally, but PM2 also offers a remote dashboard for online monitoring of services.

ecosystem.json (PWA)

File ecosystem.json of the VSF1 PWA:

{
  "apps": [
    {
      "name": "server",
      "max_memory_restart": "1G",
      "instances": "4",
      "exec_mode": "cluster",
      "script": "./node_modules/.bin/ts-node",
      "args": "-P tsconfig-build.json ./core/scripts/server.ts",
      "ignore_watch": [
        "core/build/config.json",
        "node_modules"
      ]
    }
  ]
}

Some parts of the actual file have been dropped here

Understanding the ecosystem.json file is vital for running the VSF1 stack successfully in production. For instance, the file defines the process name that is used in PM2 commands (like status). By default, the name for the PWA is server, which I personally find highly confusing. I usually change this to pwa instead.

A Node process can be started multiple times via the instances parameter. When the option exec_mode is also set to cluster, PM2 will additionally try to run each instance on a separate CPU (on the same server). This simply aids performance. The option instances can be also set to max, but be careful because you don't want this tuning to bring down other services on the same server.

The feature of clustering brings along load balancing as well: PM2 uses a built-in load balancer that divides tasks across the Node instances. The more requests you have per second, the more you benefit from additional CPUs where Node processes are placed using the instances parameter. But there's a catch: Memory usage.

A Node instance like Express and the VSF1 API only rarely suffer from memory leaks. However, within the PWA, often Vue techniques are used that were not designed for long-lived usage on the server side. Simply things as a counter that keeps on counting, even though the component that presented that counter is no longer there, will not harm a Vue app running the browser, but it will harm a Vue app running on the server. Slowly the memory consumption of the PWA goes up. And if you let it grow endlessly, it will cause the server to become less responsive. This is where PM2 comes to the rescue: Thanks to the max_memory_restart limit, PM2 will automatically reload a process once that memory boundary is reached. Keeping it at 1G is a good start - even though the PWA process should normally only consume about 150-200Mb of memory.

This also leads to a simple calculation: With this default configuration, 4 instances and 1Gb of memory per processes, it could be that over time the PWA is consuming 4Gb. Adding more memory will not solve the problem of memory leaks. Too many restarts of Node processes will not help performance either. Intense reviewing is required to fix the memory leaks permanently.

ecosystem.json (API)

File ecosystem.json of the VSF1 API:

{
  "apps": [
    {
      "name": "api",
      "script": "./dist/src/index.js",
      "log_date_format": "YYYY-MM-DD HH:mm:ss",
      "ignore_watch": ["node_modules"]
    },
    {
      "name": "o2m",
      "script": "./dist/src/worker/order_to_magento2.js",
      "args": "start",
      "log_date_format": "YYYY-MM-DD HH:mm:ss",
      "ignore_watch": ["node_modules"]
    }
  ]
}

With the previous information, we can easily explain the configuration file for the VSF1 API as well. Except for that there is not only a single process, but there's two processes: Besides the regular Express-based VSF1 API, there is also an O2M process. This process is explained in a separate lesson, when we deal with the architecture of the VSF1 API.

Tips on using PM2

  • Rename the PWA from server to pwa
  • Tune instances and max_memory_restart carefully
  • Optionally run a separate VSF1 API instance for images
    • Create a new copy of the VSF1 API files
    • Modify config/local.json to start on port 8081
    • Modify ecosystem.json
    • Route requests for images via Nginx to port 8081, instead of 8080

It was mentioned already earlier, but maybe the PWA ecosystem.json is best modified to rename the process name from server to pwa. If you run the PWA instance on the same server as the VSF1 API, this will definitely avoid some confusion, when reviewing the PM2 status.

Make sure to tune the instances and the memory usage properly.

A more advanced tuning tip might be to use a separate instance of the VSF1 API, dedicated for handling images. The VSF1 API sits in the middle of the stack and handles a lot of traffic: Magento, additional CMS-es, the PWA and ElasticSearch. On top of this, Magento images are routed through the API, which can cause performance issues. With a larger catalog (so a lot of images) it is best to add a separate VSF1 API specifically for images. To do this, copy the files to a new instance folder (and add them to a new Git repository as well). Next, modify the port number within the configuration (for instance, use port 8081). Also modify the ecosystem.json file so that it only refers to one Node process:

{
  "apps": [
    {
      "name": "api-images",
      "script": "./dist/src/index.js",
      "log_date_format": "YYYY-MM-DD HH:mm:ss",
      "ignore_watch": ["node_modules"]
    }
  ]
}

Finally, modify the webserver configuration (Nginx or Apache) to forward image requests no longer to http://localhost:8080 but to http://localhost:8081

Summary

  • Learned what PM2 will do in production
  • Different PM2 commands
  • Modifications to the ecosystem.json

In this lesson, we learned about how PM2 guarantees both uptime and performance in production. We learned about how to use the commands. And we learned how to make the right modifications to the configuration file ecosystem.json.

Extensions

GitHub organizations

Legal information

Other Yireo sites

Get Social

About Yireo