Di dunia JavaScript sisi-server, saya seorang pemula dengan pikiran bersih dan hampir tidak berantakan. Oleh karena itu, ketika saya belajar tentang keberadaan manajer proses, dan khususnya tentang PM2 , saya segera mencoba menggunakannya untuk menjalankan beberapa layanan backend sederhana pada nodejs
untuk tujuan pendidikan mandiri. Saya sangat terkesan dengan kemampuan untuk menghubungkan modul dalam kode JS melalui import
( modul ES6 ), karena ini memungkinkan Anda untuk menggunakan kode yang sama baik di browser dan di sisi server, dan saya menuliskan layanan sederhana dengan modul ES6.
Singkatnya, saya tidak berhasil meluncurkan versi aplikasi pm2
bawah pm2
, lebih baik menggunakan forever
atau systemd
untuk menjalankan aplikasi tersebut. Di bawah cut - laporan hasil bagi mereka yang suka teks lebih lama.
Pendahuluan
Dalam konteks publikasi ini, manajer proses merujuk ke layanan yang tugas utamanya adalah memantau aplikasi nodejs
berjalan dan memulai kembali jika terjadi kerusakan. Juga, manajer proses dapat (tetapi tidak harus) mengumpulkan informasi tentang sumber daya yang dikonsumsi oleh aplikasi (prosesor, memori).
Layanan uji
Untuk manajer proses pengujian, saya menggunakan kode ini dalam layanan ES6 ( github repo ):
# src/app_es6.mjs import express from "express"; import mod from "./mod/es6.mjs"; const app = express(); const msg = "Hello World! " + mod.getName(); app.get("/", function (req, res) { console.log(msg); res.send(msg); }); app.listen(3000, function () { console.log('ES6 app listening on port 3000!'); });
dan dalam modul ES6:
# src/mod/es6.mjs export default { getName: function () { return "ES6 module is here."; } }
Layanan serupa yang dilakukan dengan modul CommonJS terlihat seperti ini:
# src/app_cjs.js const express = require("express"); const mod = require("./mod/cjs.js"); const app = express(); const msg = "Hello World! " + mod.getName(); app.get("/", function (req, res) { console.log(msg); res.send(msg); }); app.listen(3000, function () { console.log("CommonJS app listening on port 3000!"); });
Modul CJS:
# src/mod/cjs.js module.exports = { getName: function () { return "CommonJS module is here."; } };
Memulai layanan tanpa menggunakan manajer proses pada nodejs
v12.14.0:
$ node --experimental-modules ./src/app_es6.mjs # ES6-service $ node ./src/app_cjs.js # CJS-service
PM2
pm2
saat ini adalah pemimpin di antara manajer proses untuk fungsi yang diusulkan (selain mempertahankan proses dalam kondisi kerja, ada juga pengelompokan , pemantauan penggunaan sumber daya, berbagai strategi untuk memulai kembali proses).
Layanan CJS dimulai tanpa masalah ( pm2
v4.2.1):
$ pm2 start ./src/app_cjs.js -i 4

jumlah instance layanan yang ditentukan dalam kluster juga didukung tanpa masalah:
root@omen17:~# ps -Af | grep app_cjs alex 29848 29828 0 15:31 ? 00:00:00 node /.../src/app_cjs.js alex 29855 29828 0 15:31 ? 00:00:00 node /.../src/app_cjs.js alex 29864 29828 0 15:31 ? 00:00:00 node /.../src/app_cjs.js alex 29875 29828 0 15:31 ? 00:00:00 node /.../src/app_cjs.js
Setelah membunuh satu instance ( PID 29864
), manajer proses segera mengambil yang baru ( PID 30703
):
root@omen17:~# kill -s SIGKILL 29864 root@omen17:~# ps -Af | grep app_cjs alex 29848 29828 0 15:31 ? 00:00:00 node /.../src/app_cjs.js alex 29855 29828 0 15:31 ? 00:00:00 node /.../src/app_cjs.js alex 29875 29828 0 15:31 ? 00:00:00 node /.../src/app_cjs.js alex 30703 29828 7 15:35 ? 00:00:00 node /.../src/app_cjs.js
Tetapi versi aplikasi pm2
tidak bekerja dengan benar di pm2
. Ketika meneruskan argumen "--experimental-modules" ke nodejs:
$ pm2 start ./src/app_es6.mjs -i 4 --node-args="--experimental-modules"
ternyata gambar ini:

Dalam log kita melihat:
$ pm2 log ... /home/alex/.pm2/logs/app-es6-error-2.log last 15 lines: 2|app_es6 | at /usr/lib/node_modules/pm2/node_modules/async/internal/onlyOnce.js:12:16 2|app_es6 | at WriteStream.<anonymous> (/usr/lib/node_modules/pm2/lib/Utility.js:186:13) 2|app_es6 | at WriteStream.emit (events.js:210:5) 2|app_es6 | at internal/fs/streams.js:299:10 2|app_es6 | Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/alex/work/sof_es6_pm/src/app_es6.mjs 2|app_es6 | at Object.Module._extensions..mjs (internal/modules/cjs/loader.js:1029:9) 2|app_es6 | at Module.load (internal/modules/cjs/loader.js:815:32) 2|app_es6 | at Function.Module._load (internal/modules/cjs/loader.js:727:14) 2|app_es6 | at /usr/lib/node_modules/pm2/lib/ProcessContainer.js:297:23 2|app_es6 | at wrapper (/usr/lib/node_modules/pm2/node_modules/async/internal/once.js:12:16) 2|app_es6 | at next (/usr/lib/node_modules/pm2/node_modules/async/waterfall.js:96:20) 2|app_es6 | at /usr/lib/node_modules/pm2/node_modules/async/internal/onlyOnce.js:12:16 2|app_es6 | at WriteStream.<anonymous> (/usr/lib/node_modules/pm2/lib/Utility.js:186:13) 2|app_es6 | at WriteStream.emit (events.js:210:5) 2|app_es6 | at internal/fs/streams.js:299:10
Artinya, nyatanya, pm2
tidak bisa menjalankan skrip yang menggunakan modul ES6 tanpa transpilasi. Masalah terbaru tentang topik ini dibuat pada 5 Desember 2019 (sekitar sebulan yang lalu).
selamanya
forever
adalah manajer proses terpopuler berikutnya setelah pm2
( npmtrends ). Ini adalah proyek yang lebih tua (dimulai pada 2010 melawan 2013 untuk pm2
), tetapi memiliki fokus yang lebih sempit pada fungsionalitas daripada pm2
. forever
"diasah" untuk terus mempertahankan proses tanpa tambahan pm2
tambahan dalam bentuk penyeimbangan muatan dan pemantauan sumber daya yang digunakan. Dilihat dari frekuensi komitmen, proyek berada dalam kondisi stabil (fase pengembangan aktif telah berlalu) dan Anda tidak dapat mengharapkan fungsi baru darinya. Saya tidak menemukan cara untuk meneruskan argumen ke nodejs
dari baris perintah ketika memulai forever
, tetapi ada kemungkinan seperti itu jika Anda menggunakan file konfigurasi:
{ "uid": "app_es6", "max": 5, "spinSleepTime": 1000, "minUptime": 1000, "append": true, "watch": false, "script": "src/app_es6.mjs", "command": "node --experimental-modules" }
Menjalankan aplikasi dalam versi ini terlihat seperti ini:
$ forever start forever.es6.json ... $ forever list info: Forever processes running data: uid command script forever pid id logfile uptime data: [0] app_es6 node --experimental-modules src/app_es6.mjs 3972 3979 /home/ubuntu/.forever/app_es6.log 0:0:0:3.354
Berikut adalah prosesnya sendiri:
$ ps -Af | grep es6 ubuntu 3972 1 0 12:01 ? 00:00:00 /usr/bin/node /usr/lib/node_modules/forever/bin/monitor src/app_es6.mjs ubuntu 3979 3972 0 12:01 ? 00:00:00 node --experimental-modules /home/ubuntu/sof_es6_pm/src/app_es6.mjs
Ketika proses "terbunuh" ( PID 3979
), manajer secara teratur memunculkan yang baru ( PID 4013
):
$ kill -s SIGKILL 3979 ubuntu@vsf:~/sof_es6_pm$ ps -Af | grep es6 ubuntu 3972 1 0 12:01 ? 00:00:00 /usr/bin/node /usr/lib/node_modules/forever/bin/monitor src/app_es6.mjs ubuntu 4013 3972 4 12:10 ? 00:00:00 node --experimental-modules /home/ubuntu/sof_es6_pm/src/app_es6.mjs
forever
melakukan pekerjaan yang sangat baik untuk meluncurkan aplikasi yang menggunakan modul ES6, tetapi pertanyaan muncul, mengapa menarik forever
pada sistem linux jika fungsi serupa dapat dicapai melalui sumber daya OS sendiri?
systemd
systemd memungkinkan Anda untuk membuat layanan di lingkungan linux dan mengontrol peluncurannya, termasuk jika terjadi crash mendadak. Cukup membuat file unit dengan deskripsi layanan ( ./app_es6.service
):
[Unit] Description=Simple web server with ES6 modules. After=network.target [Service] Type=simple Restart=always PIDFile=/run/app_es6.pid WorkingDirectory=/home/ubuntu/sof_es6_pm ExecStart=/usr/bin/nodejs --experimental-modules /home/ubuntu/sof_es6_pm/src/app_es6.mjs [Install] WantedBy=multi-user.target
dan menautkannya ke direktori /etc/systemd/system
(path harus mutlak dalam file unit). Opsi untuk memulai kembali layanan jika tiba-tiba berhenti adalah:
Restart=always
Layanan diluncurkan sebagai berikut:
# systemctl start app_es6.service # systemctl status app_es6.service ● app_es6.service - Simple web server with ES6 modules. Loaded: loaded (/home/ubuntu/sof_es6_pm/app_es6.service; linked; vendor preset: enabled) Active: active (running) since Thu 2020-01-02 11:09:42 UTC; 9s ago Main PID: 2184 (nodejs) Tasks: 11 (limit: 4662) CGroup: /system.slice/app_es6.service └─2184 /usr/bin/nodejs --experimental-modules /home/ubuntu/sof_es6_pm/src/app_es6.mjs Jan 02 11:09:42 vsf systemd[1]: Started Simple web server with ES6 modules.. Jan 02 11:09:42 vsf nodejs[2184]: (node:2184) ExperimentalWarning: The ESM module loader is experimental. Jan 02 11:09:42 vsf nodejs[2184]: ES6 app listening on port 3000!
Ketika proses "dibunuh" ( PID 2184
), systemd
secara teratur memunculkan yang baru ( PID 2233
):
# ps -Af | grep app_es6 root 2184 1 0 11:09 ? 00:00:00 /usr/bin/nodejs --experimental-modules /home/ubuntu/sof_es6_pm/src/app_es6.mjs # kill -s SIGKILL 2184 # ps -Af | grep app_es6 root 2233 1 3 11:10 ? 00:00:00 /usr/bin/nodejs --experimental-modules /home/ubuntu/sof_es6_pm/src/app_es6.mjs
Artinya, systemd
melakukan hal yang sama seperti forever
, tetapi pada tingkat yang lebih mendasar.
Strongloop
Ketika meninjau opsi implementasi untuk manajer proses, StrongLoop sering muncul. Namun, sangat terlihat bahwa proyek ini telah berhenti berkembang (versi terbaru 6.0.3 dirilis 3 tahun lalu ). Saya bahkan tidak dapat menginstalnya di Ubuntu 18.04 melalui npm
:
# npm install -g strongloop npm WARN deprecated swagger-ui@2.2.10: No longer maintained, please upgrade to swagger-ui@3. ... npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/2020-01-02T11_25_15_473Z-debug.log
Melalui yarn
paket itu diinstal, meskipun ada banyak pesan tentang versi ketergantungan yang tidak sesuai dan kesalahan instalasi, namun, saya menolak untuk mempelajari StronLoop.
Alat Pengembang
Sangat sering di sebelah pm2
dan forever
ada paket seperti nodemon , watch , onchange . Alat-alat ini bukan manajer proses, tetapi mereka memungkinkan Anda untuk memonitor perubahan dalam file dan menjalankan perintah yang melekat pada perubahan ini (termasuk me-restart aplikasi).
Ringkasan
Manajer proses seperti pm2
adalah layanan yang sangat berguna di dunia JS sisi server. Tapi, sayangnya, pm2
itu sendiri tidak memungkinkan menjalankan aplikasi nodejs
modern (khususnya, dengan modul ES6). Karena saya tidak begitu menyukai transpilasi, manajer proses yang paling dapat diterima di nodejs
bagi saya adalah systemd
tradisional (atau alternatifnya ). Namun, saya akan senang menggunakan pm2
segera setelah pm2
dapat mendukung aplikasi dengan modul ES6.