我是Node的新手,并关注Ryan Lewis出色的AWS Developer教程。在该课程中,我们将学习使用来自AWS Marketplace的Bitnami Node.js映像将Node.js应用程序部署到AWS EC2。为了进行一些练习,我想使用systemd
将应用程序转换为服务,以便在重新启动后将其恢复。但是,经过大量调试后,我发现该服务似乎一直在重新启动,并且该应用程序从未上线。这可能是由应用程序的启动方式引起的。它使用forever
CLI工具运行。手动运行npm start
时,看到以下输出:
npm start
> [email protected] prestart /home/bitnami/hamstercourse
> npm run build
> [email protected] build /home/bitnami/hamstercourse
> webpack
(node:19917) DeprecationWarning: Chunk.modules is deprecated. Use Chunk.getNumberOfModules/mapModules/forEachModule/containsModule instead.
Hash: aa4bec1a367d114f2c7f
Version: webpack 3.3.0
Time: 12349ms
Asset Size Chunks Chunk Names
application.min.js 363 kB 0 [emitted] [big] application
stylesheet.css 13.4 kB 0 [emitted] application
[10] ./node_modules/react-redux/es/index.js + 14 modules 37.6 kB {0} [built]
[18] ./node_modules/react-router-dom/es/index.js + 13 modules 11.9 kB {0} [built]
[59] ./node_modules/redux/es/index.js + 6 modules 21.3 kB {0} [built]
[62] ./node_modules/react-router-redux/es/index.js + 4 modules 5.87 kB {0} [built]
[105] ./app/index.jsx 1.86 kB {0} [built]
[209] ./app/router.jsx 2.85 kB {0} [built]
[211] ./app/routes/index.jsx 1.65 kB {0} [built]
[287] ./app/reducers/index.js 316 bytes {0} [built]
[288] ./app/reducers/hamsters.js 717 bytes {0} [built]
[289] ./app/reducers/races.js 649 bytes {0} [built]
[290] ./app/reducers/user.js 2.32 kB {0} [built]
[291] ./app/reducers/leaderboards.js 355 bytes {0} [built]
[292] ./app/reducers/status.js 285 bytes {0} [built]
[293] ./app/index.less 41 bytes {0} [built]
[326] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/index.less 247 bytes [built]
+ 312 hidden modules
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/index.less 247 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Config/index.less 485 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/User/index.less 275 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Leaderboards/index.less 485 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Races/index.less 485 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Race/index.less 485 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Main/index.less 501 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Login/index.less 488 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Hamster/index.less 485 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Hamsters/index.less 617 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
[0] ./node_modules/css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./node_modules/less-loader/dist!./app/scenes/Main/Hero/index.less 827 bytes {0} [built]
+ 1 hidden module
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
Child extract-text-webpack-plugin:
2 modules
> [email protected] start /home/bitnami/hamstercourse
> forever stopall && ./node_modules/.bin/forever start index.js
info: No forever processes running
warn: --minUptime not set. Defaulting to: 1000ms
warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info: Forever processing file: index.js
然后该过程转到后台,并且可以使用forever list
,forever stop
等进行管理。如here所述,systemd
杀死了后台进程(并且有充分的理由)。
为了证实我的怀疑,我尝试过这样运行服务:
[Unit]
Description=Node.js Hamster Http Server
[Service]
PIDFile=~/hamster-99.pid
User=bitnami
Group=bitnami
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
KillSignal=SIGQUIT
WorkingDirectory=/home/bitnami/hamstercourse
ExecStart=/opt/bitnami/nodejs/bin/node /home/bitnami/hamstercourse/index.js
[Install]
WantedBy=multi-user.target
并且在启用服务并重新加载守护进程之后,输出为:
hamster.service - Node.js Hamster Http Server
Loaded: loaded (/etc/systemd/system/hamster.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2019-06-26 10:57:46 UTC; 28min ago
Main PID: 19847 (.node.bin)
Tasks: 11
Memory: 26.8M
CPU: 2.019s
CGroup: /system.slice/hamster.service
+-19847 /opt/bitnami/nodejs/bin/.node.bin /home/bitnami/hamstercourse/index.js
Jun 26 10:57:46 ip-172-31-35-115 systemd[1]: hamster.service: Main process exited, code=dumped, status=3/QUIT
Jun 26 10:57:46 ip-172-31-35-115 systemd[1]: Stopped Node.js Hamster Http Server.
Jun 26 10:57:46 ip-172-31-35-115 systemd[1]: hamster.service: Unit entered failed state.
Jun 26 10:57:46 ip-172-31-35-115 systemd[1]: hamster.service: Failed with result 'core-dump'.
Jun 26 10:57:46 ip-172-31-35-115 systemd[1]: Started Node.js Hamster Http Server.
Jun 26 10:57:48 ip-172-31-35-115 node[19847]: Server started at http://localhost:3000
因此,好消息是:这实际上在运行服务。欢呼!但是,它跳过了npm start
实际运行的许多基本步骤(如缩小应用程序),并且当然不会通过forever
运行应用程序。可以讨论在作为服务运行时是否需要使用像forever
这样的管理工具,但是应该可以在不更改应用程序的情况下从systemd
运行它,对吗?那我该怎么办呢?
更新:
我刚刚找到https://unix.stackexchange.com/questions/308311/systemd-service-runs-without-exiting,并尝试在单位文件中使用Type=forking
。这实际上似乎起作用。但这是路吗?还是还有另一种最佳做法?
如果设置为分叉,则预期该进程配置为ExecStart =将在启动过程中调用fork()。父母当启动完成并且所有建立了沟通渠道。孩子继续奔跑主要服务流程,服务经理将考虑该单元父进程退出时启动。这是行为传统的UNIX服务。如果使用此设置,建议也使用PIDFile =选项,以便systemd可以可靠地识别服务的主要过程。 systemd将继续启动父流程退出后立即跟进。
这就是forever
的工作方式。另请注意,apache2
服务也使用Type=forking
。