ฉันจะทราบได้อย่างไรว่าบริการ systemctl ของฉันไม่เริ่มทำงานบน CentOS 7


12

ฉันใช้ CentOS 7 ฉันจะทราบได้อย่างไรว่าเหตุใดบริการไม่สามารถเริ่มต้นได้ ฉันได้สร้างบริการนี้

[rails@server ~]$ sudo cat /usr/lib/systemd/system/nodejs.service
[Unit]
Description=nodejs server

[Service]
User=rails
Group=rails
ExecStart=/home/rails/NodeJSserver/start.sh
ExecStop=/home/rails/NodeJSserver/stop.sh

[Install]
WantedBy=multi-user.target

ไฟล์ชี้ไปที่นี้

[rails@server ~]$ cat /home/rails/NodeJSserver/start.sh
#!/bin/bash

forever start /home/rails/NodeJSserver/server.js

ฉันสามารถเรียกใช้ไฟล์นี้ได้ด้วยตัวเอง แต่เมื่อฉันลองเรียกใช้เป็นส่วนหนึ่งของบริการฉันสังเกตว่าเซิร์ฟเวอร์ nodeJS ของฉันไม่เริ่มทำงาน แม้ว่าฉันจะตรวจสอบ "sudo systemctl --state = ล้มเหลว" ฉันไม่เห็นข้อผิดพลาดใด ๆ ...

[rails@server ~]$ sudo systemctl enable NodeJSserver
[rails@server ~]$ sudo systemctl start NodeJSserver
[rails@server ~]$
[rails@server ~]$
[rails@server ~]$ forever list
info:    No forever processes running
[rails@server ~]$
[rails@server ~]$
[rails@server ~]$ sudo systemctl --state=failed
  UNIT                           LOAD   ACTIVE SUB    DESCRIPTION
● nginx.service                  loaded failed failed The nginx HTTP and reverse proxy server
● systemd-sysctl.service         loaded failed failed Apply Kernel Variables
● systemd-vconsole-setup.service loaded failed failed Setup Virtual Console

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

3 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

ฉันจะทราบได้อย่างไรว่าเหตุใดบริการของฉันจึงไม่เริ่มทำงาน


journalctl -u nodejsควรให้ข้อความแสดงข้อผิดพลาดที่มีความหมายมากกว่านี้แก่คุณ
Federico klez Culloca

ฉันได้รับข้อความ "ไม่พบไฟล์เจอร์นัล"
เดฟ

sudo journalctl ควรใช้งานได้ และภายใน start.sh ดูว่ามันเปลี่ยนเส้นทางไฟล์บันทึกผลลัพธ์ไปยังที่อื่นหรือไม่
rogerdpack

คำตอบ:


13

บริการของคุณไม่มีType=ระบุไว้ใน[Service]ส่วนจึงจะถือว่าคุณมีความหมายsystemdType=simple

นั่นหมายถึงsystemdจะคาดว่ากระบวนการที่เริ่มต้นExecStart=จะยังคงทำงานต่อไปตราบใดที่บริการยังทำงานอยู่ แต่ดูเหมือนว่าคุณstart.shจะรันเพียงคำสั่งเดียวแล้วออก นั่นคือคำสั่ง : เริ่มต้นคำสั่งเป้าหมายเป็น daemon หรือในคำอื่น ๆ ในพื้นหลัง ทันทีที่คำสั่งเสร็จสิ้นเชลล์ที่รันจะออกจากการทำงานforeverforever startforever startstart.sh

ณ จุดsystemdนี้ถือว่าบริการนี้ล้มเหลว แต่เดี๋ยวก่อนกลุ่มควบคุมที่กำหนดไว้สำหรับบริการนั้นยังคงมีกระบวนการทำงานอยู่ "ดังนั้น" คิดว่าsystemd"ไม่เพียง แต่มันจะล้มเหลวเท่านั้น แต่ยังทำให้เกิดความยุ่งเหยิงหลังจากนั้นเอง เนื่องจากไม่มีKillMode=หรือไม่ได้KillSignal=ระบุให้systemdดำเนินการต่อด้วยค่าเริ่มต้นและส่ง SIGTERM สำหรับกระบวนการที่เหลืออยู่ในกลุ่มควบคุมนั้นและหากกระบวนการเหล่านั้นไม่หยุดในเวลาที่เหมาะสมให้ติดตามด้วย SIGKILL หลังจากนั้นกระบวนการ NodeJS ที่แท้จริงของคุณจะตายรับประกัน

วิธีแก้ไข

เนื่องจากคำสั่งที่คุณรันด้วยExecStart=จะออกจากทันทีที่เซิร์ฟเวอร์จริงเริ่มทำงานคุณจึงไม่สามารถใช้ค่าเริ่มต้นType=simpleได้ คุณต้องระบุประเภทบริการอื่น

Type=forkingคุณสามารถใช้ ด้วยประเภทนี้man systemd.serviceแนะนำให้ใช้PIDFile=ตัวเลือกดังนั้นหากเซิร์ฟเวอร์ NodeJS ของคุณสร้างไฟล์ PID สำหรับตัวเอง (หรือคุณเพิ่มตัวเลือกในforeverคำสั่งเพื่อให้สร้างไฟล์ขึ้นมา) คุณควรแจ้งให้systemdทราบว่าจะอยู่ที่ไหน

[Service]
Type=forking
PIDFile=/absolute/path/to/nodejs.pid
User=rails
... <the rest as before>

หากType=forkingไม่ได้ผลสำหรับคุณแล้วคุณสามารถระบุด้วยType=oneshotRemainAfterExit=yes

ที่ทำให้systemdเพียงเรียกใช้ExecStart=คำสั่งเมื่อเริ่มบริการของคุณและExecStop=เมื่อหยุดมันและไม่สนใจสิ่งอื่นใด

systemdจะยังคงจำได้ว่าบริการถูกตั้งค่าล่าสุดในสถานะหยุดหรือเริ่มแล้ว ดังนั้นหากคุณตั้งค่าบริการอื่นให้ขึ้นอยู่กับบริการนี้และจากนั้นหยุดบริการ NodeJS ของคุณด้วยตนเองบริการอื่นจะไม่หยุดโดยอัตโนมัติและจะไม่มีข้อผิดพลาดในการส่งคืนข้อผิดพลาดเมื่อไม่สามารถใช้บริการ NodeJS ของคุณได้


ตัวเลือกที่สามคือการข้ามforeverคำสั่งทั้งหมดและปล่อยให้systemdงานเริ่มต้นกระบวนการ NodeJS ใหม่ ในกรณีนั้นnodejs.serviceหน่วยทั้งหมดของคุณจะเป็น:

[Unit]
Description=nodejs server

[Service]
User=rails
Group=rails
ExecStart=/home/rails/NodeJSserver/server.js
Restart=always

[Install]
WantedBy=multi-user.target

คุณสามารถเพิ่มตัวเลือกอื่น ๆ

ตัวอย่างเช่นคุณสามารถระบุRestartSec=5เพื่อระบุการสลีป 5 วินาทีก่อนที่จะพยายามเริ่มบริการใหม่ถ้ามันตายโดยไม่คาดคิดเพื่อหลีกเลี่ยงการทรัพยากร hogging ระบบโดยพยายามเริ่มต้นใหม่บ่อยครั้งถ้าบริการของคุณตายทันทีหลังจากเริ่มใหม่ด้วยเหตุผลบางประการ (ค่าเริ่มต้นRestartSec=คือ 100 ms.)

หรือถ้าคุณต้องการให้บริการเริ่มต้นใหม่ถ้ามันคืนค่าสถานะการออกเฉพาะบางอย่าง แต่พิจารณาว่าล้มเหลวกับผู้อื่นนั้นก็มีตัวเลือกสำหรับมันเช่นกัน


ฉันมีบริการที่ไม่หยุดและไม่เริ่มต้นอย่างถูกต้อง (มันเริ่มต้น แต่กระบวนการ systemctl ไม่เคยออก) เพียงแค่ต้องการเพิ่มสิ่งนั้นในกรณีของฉันสิ่งที่ฉันต้องทำคือเพิ่มลงRestart=alwaysในไฟล์. service config ของฉัน
Andy Forceno
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.