Trong systemd, sự khác biệt giữa After = và Request = là gì?


54

Tôi đang tạo một tệp systemd .service và tôi cần trợ giúp để hiểu sự khác biệt giữa Requires=After=. Các trang người đàn ông nói rằng Requires="yêu cầu phụ thuộc cấu hình trên các đơn vị khác." và After="Định cấu hình phụ thuộc thứ tự giữa các đơn vị." Có gì khác biệt?

Câu trả lời:


44

After=cấu hình thứ tự dịch vụ (chỉ X sau Y), trong khi Requires=phụ thuộc trạng thái. Nếu bạn không chỉ định một đơn đặt hàng, một dịch vụ tùy thuộc vào một đơn hàng khác sẽ được bắt đầu cùng lúc với dịch vụ mà nó phụ thuộc. Ngoài ra, theo cách tôi hiểu (mặc dù hiện tại tôi không thể kiểm tra và không tìm thấy tài liệu tham khảo), After=là một "khớp nối lỏng lẻo" và một dịch vụ có tuyên bố như vậy vẫn sẽ chạy nếu không có tên trong After=dòng hoàn toàn không bắt đầu, trong khi Require=sẽ ngăn chặn nó bắt đầu nếu yêu cầu không được đáp ứng.

Trích dẫn https://www.freedesktop.org/software/systemd/man/systemd.unit.html :

Yêu cầu =

Định cấu hình phụ thuộc yêu cầu vào các đơn vị khác. Nếu đơn vị này được kích hoạt, các đơn vị được liệt kê ở đây cũng sẽ được kích hoạt. Nếu một trong các đơn vị khác bị vô hiệu hóa hoặc kích hoạt không thành công, đơn vị này sẽ bị hủy kích hoạt. Tùy chọn này có thể được chỉ định nhiều lần hoặc nhiều đơn vị phân tách không gian có thể được chỉ định trong một tùy chọn trong đó trường hợp phụ thuộc yêu cầu cho tất cả các tên được liệt kê sẽ được tạo. Lưu ý rằng các phụ thuộc yêu cầu không ảnh hưởng đến thứ tự dịch vụ được bắt đầu hoặc dừng. Điều này phải được cấu hình độc lập với các tùy chọn After = hoặc Before =. Nếu một đơn vị foo.service yêu cầu một đơn vị bar.service như được định cấu hình với Yêu cầu = và không có thứ tự nào được định cấu hình với After = hoặc Before =, thì cả hai đơn vị sẽ được khởi động đồng thời và không có bất kỳ độ trễ nào giữa chúng nếu foo.service được kích hoạt. Thường

Trước =, Sau =

Một danh sách ngăn cách không gian của các tên đơn vị. Định cấu hình phụ thuộc thứ tự giữa các đơn vị. Nếu một đơn vị foo.service chứa một cài đặt Before = bar.service và cả hai đơn vị đang được khởi động, quá trình khởi động của bar.service sẽ bị trì hoãn cho đến khi foo.service được khởi động. Lưu ý rằng cài đặt này độc lập và trực giao với các phụ thuộc yêu cầu như được định cấu hình bởi Request =. Đây là một mẫu chung để bao gồm một tên đơn vị trong cả tùy chọn After = và Request =, trong trường hợp đó, đơn vị được liệt kê sẽ được bắt đầu trước khi đơn vị được cấu hình với các tùy chọn này. Tùy chọn này có thể được chỉ định nhiều lần, trong trường hợp đó phụ thuộc thứ tự cho tất cả các tên được liệt kê được tạo. After = là nghịch đảo của Before =, tức là while After = đảm bảo rằng đơn vị được cấu hình được khởi động sau khi đơn vị được liệt kê kết thúc khởi động, Before = đảm bảo ngược lại, tức là thiết bị được cấu hình được khởi động đầy đủ trước khi thiết bị được liệt kê được khởi động. Lưu ý rằng khi hai đơn vị có sự phụ thuộc thứ tự giữa chúng bị tắt, nghịch đảo của thứ tự khởi động được áp dụng. tức là nếu một đơn vị được cấu hình với After = trên đơn vị khác, đơn vị trước bị dừng trước đơn vị sau nếu cả hai bị tắt. Cho hai đơn vị với bất kỳ sự phụ thuộc thứ tự nào giữa chúng, nếu một đơn vị bị tắt và đơn vị kia được khởi động, thì tắt máy được đặt hàng trước khi khởi động. Sẽ không có vấn đề gì nếu phụ thuộc thứ tự là After = hoặc Before =. Nó cũng không quan trọng cái nào trong hai cái bị tắt, miễn là cái này bị tắt và cái kia được khởi động. Việc tắt máy được ra lệnh trước khi khởi động trong mọi trường hợp. Nếu hai đơn vị không có phụ thuộc đặt hàng giữa chúng, chúng sẽ bị tắt hoặc khởi động đồng thời,


7
Một phụ thuộc là gì nếu không phải là một tuyên bố của trật tự? (nghiêm túc ... tôi không hiểu sự khác biệt)
TomOnTime

Xem chỉnh sửa của tôi. Hiểu biết của tôi: After=Xsẽ có nghĩa là "Thực hiện việc này sau X nếu X hoàn thành", trong khi Require=Xđó có nghĩa là "hoàn toàn không làm điều này nếu bạn không thể làm X".
Sven

Các Before=phần của trang người đàn ông dường như xác nhận điều này. If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up Theo cách tôi hiểu, việc đặt hàng sẽ không được thực thi nếu bar.servicekhông bắt đầu bằng mọi cách và foo.servicesẽ bắt đầu bình thường.
Sven

10

Một trong những khác biệt chính là,

  • After chỉ kiểm tra nếu đơn vị đã được kích hoạt và không kích hoạt rõ ràng các đơn vị được chỉ định.
  • Các đơn vị được liệt kê trong Requiresđược kích hoạt cùng với các đơn vị. Nếu bất kỳ đơn vị yêu cầu nào không khởi động, thiết bị không được kích hoạt.

Xem xét tôi có một tập tin đơn vị test-app.service,

[Unit]
Description=test app
After=network-online.target

Đây là những gì sẽ xảy ra khi tuyên bố này được thực thi,

  • Afterkiểm tra nếu network-online.target.
  • nếu network-online.targetkhông bắt đầu, nó sẽ đợi
  • test-appchỉ bắt đầu sau khi network-online.targethoạt động

Nếu tôi có Requiresthay vào đó,

[Unit]
Description=test app
Requires=network-online.target

Đây là những gì sẽ xảy ra khi tuyên bố này được thực thi,

  • network-online.targettest-appđược kích hoạt cùng nhau
  • nếu network-online.targetkhông khởi động test-appsẽ không được kích hoạt.

2

systemd là một người quản lý công việc. Trang người đàn ông không chính xác như cách mọi thứ hoạt động.

Khi bạn khởi động, những gì systemd thực hiện là xây dựng một giao dịch bao gồm các công việc cho công việc neo (tức là bắt đầu công việc cho default.target). Những gì tất cả những phụ thuộc và mối quan hệ này làm là xác định cách thức và những công việc sẽ được kích hoạt. Đặt hàng xác định (các) công việc mà mọi công việc khác sẽ chờ đợi. Do đó, đơn vị default.target là trung tâm của tất cả điều này, đó là lý do tại sao khi cho phép các đơn vị bạn sử dụng một phụ thuộc ngược mà thông qua systemctl cho phép tạo ra một liên kết biểu tượng hệ thống tệp biểu thị một hệ thống phụ thuộc chuyển tiếp có thể đi theo (cũng là lý do tại sao bạn cần liên kết hệ thống tệp trong địa điểm đầu tiên). Tương tự là khi bạn tự khởi động một số đơn vị, thì đơn vị đó là neo và giao dịch được tính toán.

Không đi quá chi tiết, tôi sẽ giải thích những gì Yêu cầu = và Sau = làm.

Yêu cầu = sẽ khiến systemd kích hoạt công việc bắt đầu cho đơn vị được yêu cầu khi bạn bắt đầu kích hoạt công việc (rõ ràng hoặc thông qua một phụ thuộc: không có sự phân biệt trong nội bộ). Nó cũng có đặc tính kích hoạt công việc dừng đối với bạn khi đơn vị này bị dừng (lưu ý: đã dừng, không tự tắt) hoặc khởi động lại. Điều này có nghĩa là nếu một số phụ thuộc / systemctl khiến nó dừng / khởi động lại, bạn cũng sẽ dừng / khởi động lại. Tuy nhiên, nếu nó tự đi xuống, bạn sẽ không dừng lại, vì không có việc làm và sự thay đổi trạng thái xảy ra mà không có sự tham gia của hệ thống. Đó là nơi bạn sẽ sử dụng BindsTo = (tương tự như các đơn vị thiết bị, có thể không hoạt động mà không có sự tham gia của systemd, vì những lý do rõ ràng).

Bây giờ, việc sử dụng After = được khuyến nghị là Request = alone là không phù hợp với những gì nó làm: hủy yêu cầu nếu công việc bắt đầu thất bại. Tuy nhiên, việc hủy này chỉ thực hiện các công việc wrt, tức là nếu đơn vị kia không xác định thứ tự, systemd kích hoạt song song và nếu công việc bắt đầu của nó kết thúc trước khi công việc bắt đầu của bạn thất bại, thực tế nó sẽ không bị hủy (thực tế không thể hủy bỏ) . Sử dụng After = có nghĩa là công việc khác tiếp tục chờ cho đến khi công việc bắt đầu của đơn vị được yêu cầu kết thúc và tùy thuộc vào kết quả, nếu thất bại, công việc bắt đầu chờ đợi của đơn vị của bạn bị hủy với kết quả công việc JOB_DEPENDENCY (tại sao bạn sử dụng màu vàng [DEPEND] lúc khởi động cho những trường hợp như vậy). Do đó, hiệu ứng vô hiệu này là không xác định nếu không sử dụng After =.

Đây là lý do tại sao sử dụng Wants = không có After = sẽ ổn nếu bạn không muốn chờ đợi sự khởi động của đơn vị khác: vì không có sự vô hiệu ở đó, vì vậy không có cuộc đua. Trong trường hợp đó, nó không hơn một cơ chế đồng bộ hóa.

Ngoài ra, bạn cũng có thể kích hoạt cả khi khởi động và không yêu cầu lẫn nhau và chỉ xác định thứ tự, trong trường hợp đó, khi cả hai được kéo như một phần của cùng một giao dịch, chúng sẽ được đặt hàng (hoặc nếu công việc cho người khác được kích hoạt trong khi công việc cho đơn vị mà nó muốn chạy sau khi chạy, trước tiên nó sẽ đợi nó kết thúc, trên các giao dịch).

Bây giờ nếu không có việc làm, đặt hàng không có hiệu lực cho các đơn vị nói. Tuy nhiên, thường có một công việc, do hậu quả của việc sử dụng các phụ thuộc như Request = và Wants =, hoặc cả hai bị kéo vào một lúc và xác định một số thứ tự, trong trường hợp họ chờ đợi công việc của đơn vị khác.

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.