This is the 29th day of my participation in the August Gwen Challenge.

Node.js runs single-process by default and can use up to 512MB of memory for 32-bit systems and up to 1GB for 64-bit systems. For computers with multiple cpus, this is inefficient because only one core is running and the rest are idle. Pm2 uses node’s native Cluster module to solve this problem.

Pm2 is an application process manager with load balancing functionality that enables Node services to run in the background.

The installation

npm install pm2 -g
Copy the code

Common PM2 commands

App.js is the startup program of apI-service and is managed by PM2 in the production environment

  • Start the
Pm2 start app.js --name api-service pm2 start app.js --watch # When the app.js file is changed, pm2 will be automatically reloadedCopy the code

  • Check the process
Pm2 list pm2 show 0 or # pm2 info 0Copy the code

  • monitoring
pm2 monit
Copy the code

  • stop
Pm2 stop all stop all processes in the Pm2 list pm2 stop 0 Stop all processes in the PM2 listCopy the code
  • overloading
Reload all pm2 processes pm2 0 reload all pm2 processesCopy the code
  • restart
Pm2 restart 0 restart all processes in the Pm2 listCopy the code
  • Example Delete the PM2 process
Pm2 delete all delete all processes in the pm2 listCopy the code

Autostart file

To generate the script

pm2 ecosystem
Copy the code

Create a file: / API – service/ecosystem. Config. Js

module.exports = {
    apps: [
        {
            name: "api-service",
            script: "app.js",
            merge_logs: true,
            max_restarts: 20,
            instances: 1,
            max_memory_restart: "2G",
            cwd: "/website/api-service/",
            env: {
                NODE_ENV: "development",
            },
            env_production: {
                NODE_ENV: "production",
            },
        },
    ],
};
Copy the code

Description:

  • Apps: JSON structure. Apps is an array, and each array member corresponds to an application running in PM2

  • Name: Indicates the name of the application

  • CWD: the directory where the application resides

  • Script: script path of the application

  • Exec_interpreter: The script type for the application. The shell used here is nodeJS by default.

  • Min_uptime: the amount of restarts for max_restarts is triggered if the application exits within 60 seconds

  • Restarts for max_restarts: Restarts for the application for an unexpected exit, 15 times by default (counting from 0)

  • Exec_mode: Application startup mode, which is set to Cluster_mode (cluster) and fork by default

  • Error_file: error log file of the custom application

  • Out_file: custom application log file

  • Pid_file: Pid file for custom application

  • Watch: Whether to enable monitoring mode. The default is false. If set to true, pM2 will automatically reload when the application changes.

Execute the script

pm2 start /website/api-service/ecosystem.config.js
Copy the code

restart

sudo reboot
Copy the code

Check the process

pm2 list
Copy the code

Dockerfile

The installation, deployment, startup and other operations described above can be simply completed using Docker. For the use of Docker, you can refer to Docker for WEB Developers. In a typical project complete environment with Node as the backend service and Vue or Angular as the front end, the production environment can choose Nginx + Node + pM2 and Nginx as the portal to the Web project. Nginx :1.21.1-alpine: nginx:1.21.1-alpine: nginx:1.21.1-alpine

The FROM nginx: 1.21.1 - alpine # Stream the nginx logs to stdout and stderr RUN ln - sf/dev/stdout/var/log/nginx/access. Log &&\ ln -sf /dev/stderr /var/log/nginx/error.log # Install nodejs ENV NODE_VERSION 16.6.1 RUN addgroup -g 1000 node \ && adduser -u 1000 -G node -s /bin/sh -D node \ && apk add --no-cache \ libstdc++ \ && apk add --no-cache --virtual .build-deps \ curl \ && ARCH= && alpineArch="$(apk --print-arch)" \ && case "${alpineArch##*-}" in \ x86_64) \ ARCH='x64' \ CHECKSUM="9c8438a8d9a1e268153812d1d3f7f63b02283e2082dcd39274674f897496a22a" \ ;; A \ *);; \ esac \ && if [ -n "${CHECKSUM}" ]; then \ set -eu; \ curl -fsSLO --compressed "https://unofficial-builds.nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz"; \ echo "$CHECKSUM node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" | sha256sum -c - \ && tar -xJf "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \ && ln -s /usr/local/bin/node /usr/local/bin/nodejs; \ else \ echo "Building from source" \ # backup build && apk add --no-cache --virtual .build-deps-full \ binutils-gold \  g++ \ gcc \ gnupg \ libgcc \ linux-headers \ make \ python3 \ # gpg keys listed at https://github.com/nodejs/node#release-keys && for key in \ 4ED778F539E3634C779C87C6D7062848A1AB005C \ 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \ 74F12602B6F1C4E913FAA37AD3A89613643B6201 \ 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \ 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \ C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \ DD8F2338BAE7501E3DD5AC78C273792F7D83545D \ A48C2BEE680E841632CD4E44F07496B3EB3C1762 \ 108F52B48DB57BB0CC439B2997B01419BD92F80A \ B9E2F5981AA6E0CD28160D9FF13993A75599653C \ ; do \ gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \ done \ && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION.tar.xz" \ && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ && grep " node-v$NODE_VERSION.tar.xz\$" SHASUMS256.txt | sha256sum -c - \ && tar -xf  "node-v$NODE_VERSION.tar.xz" \ && cd "node-v$NODE_VERSION" \ && ./configure \ && make -j$(getconf _NPROCESSORS_ONLN) V=  \ && make install \ && apk del .build-deps-full \ && cd .. \ && rm -Rf "node-v$NODE_VERSION" \ && rm "node-v$NODE_VERSION.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt; \ fi \ && rm -f "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" \ && apk del .build-deps \ # smoke tests && node --version \ &&npm --version # ENV SERVICE_WORKDIR=/webapps/api-service WORKDIR $SERVICE_WORKDIR COPY ./api-service/package.json /webapps/api-service/package.json RUN npm install && npm cache clean --force RUN npm install pm2 -g COPY ./api-service/config /webapps/api-service/config COPY ./api-service/src/controllers /webapps/api-service/src/controllers COPY ./api-service/src/models /webapps/api-service/src/models COPY ./api-service/src/services /webapps/api-service/src/services COPY ./api-service/src/routers /webapps/api-service/src/routers COPY ./api-service/src/utils /webapps/api-service/src/utils COPY ./api-service/app.js /webapps/api-service COPY ./api-service/ecosystem.config.js /webapps/api-service RUN mkdir ~/.pm2 RUN chmod 755 -R ~/.pm2 # VUE front WORKDIR /webapps/app COPY./dist /webapps/app COPY./etc/nginx/default.conf /etc/nginx/conf 755 -R /webapps/app \ && chmod 755 -R /usr/local/bin \ && chmod 755 -R /webapps/api-service EXPOSE 80 WORKDIR /webapps/api-service COPY start.sh . CMD [ "./start.sh" ]Copy the code

The./start.sh script is as follows:

#! /bin/sh nginx pm2 start /webapps/api-service/ecosystem.config.js --no-daemonCopy the code

/etc/nginx/default.conf the code for the nginx configuration file is:

server{ listen 80; root /webapps/app; index index.html; charset utf-8; add_header "X-UA-Compatible" "IE=Edge,chrome=1"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; Location/API {proxy_pass http://127.0.0.1:4200; } location / { if ($request_filename ~* ^.*? .(html|htm)$){ expires -1s; add_header Cache-Control no-cache,no-store,must-revalidate; } try_files $uri $uri/ /index.html; }}Copy the code