รีสตาร์ท Systemd = ไม่ได้รับเกียรติเสมอ


53

หมายเหตุ: ผมเขียนบทความเกี่ยวกับการขนาดกลางที่อธิบายถึงวิธีการสร้างบริการและวิธีการหลีกเลี่ยงปัญหานี้โดยเฉพาะอย่างยิ่ง: การสร้างบริการ Linux กับ systemd

คำถามเดิม:


ฉันใช้ systemd เพื่อให้สคริปต์ผู้ปฏิบัติงานทำงานตลอดเวลา:

[Unit]
Description=My worker
After=mysqld.service

[Service]
Type=simple
Restart=always
ExecStart=/path/to/script

[Install]
WantedBy=multi-user.target

แม้ว่าการรีสตาร์ทจะทำงานได้ดีถ้าสคริปต์ออกจากปกติหลังจากผ่านไปสองสามนาทีฉันสังเกตว่าถ้าซ้ำ ๆ ไม่สามารถรันเมื่อเริ่มต้นได้ แต่systemdจะยอมแพ้พยายามเริ่ม:

Jun 14 11:10:31 localhost systemd[1]: test.service: Main process exited, code=exited, status=1/FAILURE
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'exit-code'.
Jun 14 11:10:31 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.
Jun 14 11:10:31 localhost systemd[1]: test.service: Start request repeated too quickly.
Jun 14 11:10:31 localhost systemd[1]: Failed to start My worker.
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'start-limit'.

ในทำนองเดียวกันถ้าสคริปต์ปฏิบัติงานของฉันล้มเหลวหลายครั้งที่มีสถานะทางออกของ255, systemdให้ขึ้นพยายามที่จะเริ่มต้นใหม่ได้:

Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'exit-code'.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Start request repeated too quickly.  
Jun 14 11:25:51 localhost systemd[1]: Failed to start My worker.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Unit entered failed state.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'start-limit'.

มีวิธีการบังคับให้มีsystemdการเสมอลองใหม่อีกครั้งหลังจากที่ไม่กี่วินาที?

คำตอบ:


53

ฉันต้องการขยายคำตอบของราหุลออกไปเล็กน้อย

SystemD พยายามที่จะเริ่มต้นใหม่ได้หลายครั้ง ( StartLimitBurst) StartLimitIntervalSecและหยุดพยายามถ้านับความพยายามที่จะมาถึงภายใน ตัวเลือกทั้งสองเป็นของ[unit]ส่วน

การหน่วงเวลาเริ่มต้นระหว่างการประมวลผลคือ 100ms ( RestartSec) ซึ่งทำให้ขีด จำกัด อัตราสามารถเข้าถึงได้เร็วมาก

SystemD จะไม่พยายามทำการรีสตาร์ทอัตโนมัติอีกต่อไปสำหรับยูนิตที่กำหนดนโยบายการรีสตาร์ท :

โปรดทราบว่าหน่วยที่กำหนดค่าไว้Restart=และที่ถึงขีด จำกัด เริ่มต้นจะไม่พยายามเริ่มต้นอีกต่อไป อย่างไรก็ตามพวกเขายังคงสามารถเริ่มต้นใหม่ด้วยตนเองในภายหลังจากจุดที่ตรรกะการเริ่มต้นใหม่จะเปิดใช้งานอีกครั้ง

คำตอบของราหุลช่วยได้เพราะความล่าช้าที่นานกว่านั้นจะป้องกันไม่ให้ไปถึงตัวนับข้อผิดพลาดภายในStartLimitIntervalSecเวลา คำตอบที่ถูกต้องคือการตั้งค่าทั้งสองRestartSecและStartLimitBurstค่าที่เหมาะสมแม้ว่า


5
ตอนนี้ฉัน (ในที่สุด) เข้าใจว่ามันทำงานอย่างไรหลังจากลองผิดลองถูกแล้วฉันจะเห็นว่าคำตอบของคุณนั้นถูกต้องที่สุด บรรทัดล่างสุดสำหรับฉัน: set StartLimitIntervalSec=0และvoilà
Benjamin

34

ใช่แล้ว คุณสามารถระบุให้ลองอีกครั้งหลังจากxวินาทีภายใต้[Service]ส่วน

[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/path/to/script

หลังจากบันทึกไฟล์คุณต้องโหลดการกำหนดค่า daemon ใหม่เพื่อให้แน่ใจว่าsystemdรับรู้ถึงไฟล์ใหม่

systemctl daemon-reload

จากนั้นเริ่มบริการใหม่เพื่อเปิดใช้งานการเปลี่ยนแปลง

systemctl restart test

ตามที่คุณร้องขอดูเอกสาร

Restart=on-failure

ฟังดูเหมือนคำแนะนำที่ดี


ดูเหมือนว่าจะทำงานได้จริงขอบคุณ! ดังนั้นเพื่อให้เข้าใจสิ่งนี้ได้ดีขึ้นโดยไม่ต้องมีRestartSecคำสั่งให้systemdพยายามรีสตาร์ทอย่างรวดเร็วมากจากนั้นเข้าสู่สถานะความล้มเหลวถาวร สิ่งที่ไม่สามารถเกิดขึ้นได้เมื่อRestartSecระบุไว้?
Benjamin

นอกจากนี้ฉันสังเกตว่ามันทำให้การรีสตาร์ท "ปกติ" ของฉันล่าช้า (ฉันตั้งใจออกจากคนงานอย่างสง่างามหลังจากผ่านไปสองสามนาที); มีวิธีหน่วงเวลาการรีสตาร์ทที่ล้มเหลวหรือไม่
Benjamin

@Benjamin ดูการอัปเดตของฉัน
Rahul

@Benjamin คุณสามารถตรวจสอบพารามิเตอร์เพิ่มเติมได้ที่นี่
ราหุล

3
การตัดสินโดยdocนั้นalwaysเป็นสิ่งที่เกินเลยon-failureไปดังนั้นมันจะไม่ช่วยได้!
Benjamin

5

systemd ยกเลิกการพยายามรีสตาร์ท

เลขที่ systemd ให้ขึ้นพยายามที่จะเริ่มต้นใหม่ได้ในขณะที่น้อย สิ่งนี้แสดงให้เห็นอย่างชัดเจนในบันทึกที่คุณจัดหา:

14 มิถุนายน 11:25:51 localhost systemd [1]: test.service: ล้มเหลวโดยมีผล 'เริ่มขีด จำกัด'

นี่คืออัตราการ จำกัด การเตะ

ความยาวของค่าเล็กน้อยในหน่วยบริการใช้การStartLimitIntervalSec=ตั้งค่า จำนวนการเริ่มต้นที่จำเป็นภายในช่วงเวลานั้นเพื่อทริกเกอร์กลไกการ จำกัด อัตราที่ระบุไว้ผ่านการStartLimitBurst=ตั้งค่า หากไม่มีสิ่งใดในระบบของคุณที่แตกต่างจาก vanilla systemd รวมถึงค่าเริ่มต้นสำหรับการตั้งค่าทั้งสองนี้แสดงว่าเป็น 5 เท่าภายใน 10 วินาที

StartLimitIntervalSec=0ปิดใช้งานการ จำกัด อัตราการใช้งานดังนั้น systemd จะลองใหม่ตลอดไปแทนที่จะยอมแพ้ แต่การทำให้บริการของคุณไม่ออกบ่อยนักหรือว่างพอระหว่างออกและเริ่มระบบใหม่ซึ่งไม่เกินขีด จำกัด อัตราที่กำหนดเป็นวิธีการที่ดีกว่า

โปรดทราบว่าการ จำกัด อัตราไม่สนใจว่าบริการของคุณจะออกจากที่ใด มันเป็นต้นเหตุของจำนวนครั้งที่พยายามเริ่ม / รีสตาร์ทโดยไม่คำนึงถึงสาเหตุ

อ่านเพิ่มเติม


5
ดูเหมือนจะยอมแพ้อย่างถาวรแม้ว่า: "ใช้งาน: ล้มเหลว (ผลลัพธ์: ขีด จำกัด เริ่มต้น) ตั้งแต่ พ.ค. 2016-06-15 01:21:24 CEST; 12 ชม. ที่ผ่านมา" มันยังคงอยู่ในสถานะนี้และสคริปต์จะไม่ถูกดำเนินการอีกครั้ง ฉันลองตั้งค่าด้วยตนเองStartLimitIntervalSec=10และStartLimitIntervalSec=5ก็ไม่มีโชค
Benjamin

5
มันจะยอมแพ้อย่างถาวรโดยค่าเริ่มต้น ดูgithub.com/systemd/systemd/issues/2416
Adam Goode

2
บรรทัดด้านล่าง: StartLimitIntervalSec=0ที่จะหยุดการป้องกันไม่ให้ขึ้นอย่างถาวรตั้ง
Benjamin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.