Khởi động lại hệ thống = luôn luôn không được vinh danh


53

Lưu ý: Tôi đã viết một bài viết trên Medium giải thích cách tạo một dịch vụ và cách tránh vấn đề cụ thể này: Tạo một dịch vụ Linux với systemd .

Câu hỏi gốc:


Tôi đang sử dụng systemd để giữ cho tập lệnh worker luôn hoạt động:

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

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

[Install]
WantedBy=multi-user.target

Mặc dù khởi động lại hoạt động tốt nếu tập lệnh thoát bình thường sau vài phút, tôi đã nhận thấy rằng nếu nó liên tục không thực thi khi khởi động, systemdsẽ bỏ cuộc khi cố gắng khởi động nó:

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'.

Tương tự, nếu tập lệnh worker của tôi thất bại nhiều lần với trạng thái thoát 255, hãy systemdtừ bỏ việc thử khởi động lại nó:

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'.

Có cách nào để buộc systemdđể luôn thử lại sau vài giây?

Câu trả lời:


53

Tôi muốn mở rộng câu trả lời của Rahul một chút.

SystemD cố gắng khởi động lại nhiều lần ( StartLimitBurst) và dừng thử nếu đạt được số lần thử StartLimitIntervalSec. Cả hai tùy chọn thuộc về [unit]phần.

Độ trễ mặc định giữa các lần thực thi là 100ms ( RestartSec) khiến giới hạn tốc độ đạt được rất nhanh.

SystemD sẽ không thử khởi động lại tự động nữa đối với các đơn vị có chính sách Khởi động lại được xác định :

Lưu ý rằng các đơn vị được cấu hình cho Restart=và đạt đến giới hạn bắt đầu không được cố gắng khởi động lại nữa; tuy nhiên, chúng vẫn có thể được khởi động lại thủ công vào thời điểm sau, từ thời điểm đó, logic khởi động lại được kích hoạt lại.

Câu trả lời của Rahul có ích, bởi vì sự chậm trễ lâu hơn ngăn chặn bộ đếm lỗi trong StartLimitIntervalSecthời gian. Câu trả lời đúng là đặt cả hai RestartSecStartLimitBurstgiá trị hợp lý mặc dù.


5
Bây giờ tôi (cuối cùng) đã hiểu nó hoạt động như thế nào, sau một vài lần thử và sai, tôi có thể thấy rằng câu trả lời của bạn là đúng nhất. Dòng dưới cùng cho tôi: thiết lập StartLimitIntervalSec=0và voilà.
Benjamin

34

Vâng , có. Bạn có thể chỉ định thử lại sau xvài giây trong [Service]phần,

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

Sau khi lưu tệp, bạn cần tải lại cấu hình daemon để đảm bảo systemdbiết về tệp mới,

systemctl daemon-reload

sau đó khởi động lại dịch vụ để cho phép thay đổi,

systemctl restart test

Như bạn đã yêu cầu, Nhìn vào tài liệu,

Restart=on-failure

Nghe có vẻ là một đề nghị tốt.


Nó dường như làm việc thực sự, cảm ơn bạn! Vì vậy, để hiểu rõ hơn về điều này, không có RestartSecchỉ thị, các systemdnỗ lực sẽ khởi động lại rất nhanh, sau đó đi vào trạng thái thất bại vĩnh viễn; một cái gì đó không thể xảy ra khi RestartSecđược chỉ định?
Benjamin

Ngoài ra, tôi đã nhận thấy rằng nó trì hoãn việc khởi động lại "bình thường" của nhân viên của tôi (Tôi cố tình thoát khỏi công nhân một cách duyên dáng sau vài phút); Có cách nào để trì hoãn khởi động lại không thành công ?
Benjamin

@Benjamin xem thông tin cập nhật của tôi
Rahul

@Benjamin bạn có thể kiểm tra ở đây để biết thêm thông số.
Raul

3
Đánh giá bởi các tài liệu , alwayslà một thay on-failurethế, vì vậy nó sẽ không giúp đỡ!
Benjamin

5

systemd từ bỏ cố gắng để khởi động lại nó

Số systemd từ bỏ cố gắng khởi động lại nó một chút . Điều này được hiển thị rõ ràng trong nhật ký mà bạn cung cấp:

Ngày 14 tháng 6 11:25:51 localhost systemd [1]: test.service: Không thành công với kết quả 'giới hạn bắt đầu' .

Đây là tỷ lệ giới hạn đá trong.

Độ dài của thời gian ngắn được chỉ định trong đơn vị dịch vụ, sử dụng StartLimitIntervalSec=cài đặt. Số lượng bắt đầu cần thiết trong khoảng đó để kích hoạt cơ chế giới hạn tốc độ được chỉ định thông qua StartLimitBurst=cài đặt. Nếu không có gì trên hệ thống của bạn khác với vanilla systemd, bao gồm cả mặc định cho hai cài đặt này, thì đó là 5 lần trong vòng 10 giây.

StartLimitIntervalSec=0vô hiệu hóa giới hạn tốc độ, vì vậy systemd sẽ thử lại mãi mãi thay vì bỏ cuộc. Nhưng làm cho dịch vụ của bạn không thoát ra thường xuyên hoặc đủ nhàn rỗi giữa các lần thoát và khởi động lại mà nó không vượt quá ngưỡng giới hạn tốc độ, là một cách tiếp cận tốt hơn.

Lưu ý rằng việc giới hạn tỷ lệ không quan tâm đến việc dịch vụ của bạn đã thoát như thế nào. Nó kích hoạt số lần thử khởi động / khởi động lại nó, bất kể nguyên nhân của chúng.

đọc thêm


5
Nó dường như từ bỏ vĩnh viễn, mặc dù: "Hoạt động: thất bại (Kết quả: giới hạn bắt đầu) kể từ Thứ Tư 2016-06-15 01:21:24 CEST; 12h trước". Nó vẫn ở trạng thái này và kịch bản không bao giờ được thực hiện lại. Tôi đã thử cài đặt bằng tay StartLimitIntervalSec=10StartLimitIntervalSec=5, không có may mắn.
Benjamin

5
Nó không từ bỏ vĩnh viễn theo mặc định. Xem github.com/systemd/systemd/issues/2416 .
Adam Goode

2
Điểm mấu chốt: để ngăn chặn nó từ bỏ vĩnh viễn, thiết lập StartLimitIntervalSec=0.
Benjamin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.