2016-03-16 14 views
10

Một dịch vụ (nói bar.service) phụ thuộc vào dịch vụ khác (nói foo.service), như dưới đâyLàm thế nào để khởi động lại một dịch vụ nếu dịch vụ phụ thuộc của nó được khởi động lại

thanh của tập tin dịch vụ:

[Unit] 
After=foo.service 
Requires=foo.service 
... 

Nếu foo.service được khởi động lại (thủ công hoặc do lỗi), làm thế nào để có thể tự động khởi động lại thanh bar.service?

+0

Bạn đã cố gắng đặt dòng 'Restart = always' trong dịch vụ của mình chưa? Tôi đoán thanh sẽ được khởi động lại ngay sau khi phụ thuộc của nó còn sống – ogs

+1

@SnP Khởi động lại "Định cấu hình liệu dịch vụ có được khởi động lại khi quá trình dịch vụ thoát, bị giết hoặc hết thời gian chờ" và do đó sẽ không giúp trừ khi thanh bị treo khi foo khởi động lại. –

+0

Khá thú vị! Cảm ơn bạn đã làm rõ – ogs

Trả lời

15

Bạn có thể sử dụng PartOf.

[Unit] 
After=foo.service 
Requires=foo.service 
PartOf=foo.service 

Từ trang systemd.unit người đàn ông:

PartOf =

cấu hình tương tự như phụ thuộc Đòi hỏi =, nhưng giới hạn để dừng lại và khởi động lại các đơn vị. Khi systemd dừng hoặc khởi động lại các đơn vị được liệt kê ở đây, hành động được truyền đến đơn vị này. Lưu ý rằng đây là phụ thuộc một chiều - các thay đổi đối với đơn vị này không ảnh hưởng đến các đơn vị được liệt kê.

+0

Lưu ý rằng 'PartOf' chỉ liên kết khởi động lại, nhưng ** không dừng lại, nâng cấp, bắt đầu ** sự kiện. Trong những trường hợp đó bạn có thể cần 'WantedBy'. [Xem câu trả lời này để biết chi tiết] (https://unix.stackexchange.com/questions/375091/how-to-get-my-systemd-service-restarted-when-its-dependency-is-upgraded) – Rennex

1

Tôi nghĩ tùy chọn cần thiết là BindsTo, nó cũng xử lý các misbehaviours quá.

[Unit] 
Requires=postgresql.service 
After=postgresql.service 
BindsTo=postgresql.service 

BindsTo =

cấu hình yêu cầu phụ thuộc, rất giống kiểu Đòi hỏi =. Tuy nhiên, kiểu phụ thuộc này mạnh hơn: ngoài tác dụng của Yêu cầu = nó tuyên bố rằng nếu đơn vị liên kết bị dừng, đơn vị này cũng sẽ bị dừng lại. Điều này có nghĩa là một đơn vị liên kết với một đơn vị khác đột nhiên vào trạng thái không hoạt động cũng sẽ bị dừng lại. Các đơn vị có thể đột ngột nhập vào trạng thái không hoạt động vì các lý do khác nhau: quy trình chính của một đơn vị dịch vụ có thể chấm dứt theo lựa chọn riêng của nó, thiết bị sao lưu của thiết bị có thể được rút phích cắm hoặc điểm gắn kết của thiết bị gắn kết có thể được tháo ra mà không có sự tham gia của hệ thống và người quản lý dịch vụ.

Khi được sử dụng cùng với After = trên cùng đơn vị, hành vi của BindsTo = thậm chí còn mạnh hơn. Trong trường hợp này, thiết bị bị ràng buộc nghiêm ngặt phải ở trạng thái hoạt động cho thiết bị này cũng ở trạng thái hoạt động. Điều này không chỉ có nghĩa là một đơn vị liên kết với một đơn vị khác đột nhiên đi vào trạng thái không hoạt động, nhưng cũng bị ràng buộc với một đơn vị khác bị bỏ qua do kiểm tra tình trạng thất bại (như ConditionPathExists =, ConditionPathIsSymbolicLink =,… - xem bên dưới) dừng lại, nó sẽ chạy. Do đó, trong nhiều trường hợp tốt nhất là kết hợp BindsTo = với After =.

0

Một giải pháp khác có thể được sử dụng ExecStartPost tùy chọn để khởi động lại bar.service (nếu nó thực hiện) khi foo.service đã (lại) bắt đầu:

# foo.service 
[Service] 
ExecStartPost=/bin/systemctl try-restart bar.service 
Restart=on-failure 
RestartSec=30s 

Các thêm Khởi động lại các tùy chọnRestartSec đảm bảo rằng foo.service sẽ tự động khởi động lại khi gặp sự cố và do đó cũng có bar.service.

Tiện ích mở rộng thứ hai của tôi là để thêm vào bar.service và đảm bảo rằng bar.service bắt đầu sau foo.dịch vụ:

# bar.service 
[Unit] 
After=foo.service 

[Service] 
Restart=on-failure 
RestartSec=30s 

này nên bắt đầu cả hai dịch vụ tự động trong trường hợp của một vụ tai nạn và bar.service sẽ được khởi động lại khi khởi động lại foo.service (do một lỗi hoặc bằng tay kích hoạt).

Các vấn đề liên quan