CentOS 7 khởi động quá nhanh và mạng chưa sẵn sàng khi thực thi các tập lệnh cron


9

Tôi vừa nâng cấp từ CentOS 6.5 lên 7.0 và tôi không hài lòng lắm vì cái mới systemdcó lẽ đang gây ra cho tôi những vấn đề. Có vẻ như nó chỉ đơn giản là khởi động quá nhanh, khởi động các quá trình không đồng bộ và làm hỏng các phụ thuộc dịch vụ.

Ví dụ: tôi có một vài thiết lập tập lệnh crondđược kích hoạt sau khi khởi động lại:

@reboot    /root/scripts/check_gmail.sh
@reboot    /root/scripts/start_gps_listener.sh

Điều này dẫn đến tất cả các loại lỗi lạ (chỉ hiển thị một trong số chúng):

Warning: stream_socket_client(): unable to connect to tcp://192.168.20.4:4001 
  (Network is unreachable) in /root/scripts/check_gmail.php on line 137
  ERROR: Network is unreachable (101)

Ở trên tôi đang viết cho một socket TCP. Nó là khá rõ ràng với tôi rằng crondđược bắt đầu trước khi mạng được khởi tạo đúng như là network is unreachable.

Điều tương tự cũng xảy ra với Apache và MySQL (MariaDB). MySQL khá chậm khi khởi động (nhiều dữ liệu) có nghĩa là cả Apache và rất nhiều crondtập lệnh khởi động của tôi đều bị lỗi vì cơ sở dữ liệu MySQL không chạy khi tập lệnh được gọi.

Tôi đã cố gắng thiết lập các phụ thuộc nhưng không có may mắn; Tôi đã nối networkmysqldịch vụ [Unit](như đã thấy systemctl list-dependencies). Lý tưởng nhất là tất cả các dịch vụ đều đợi cho đến khi MySQL hoạt động:

vi /lib/systemd/system/httpd.service
  [Unit]
  Description=The Apache HTTP Server
  After=network.target remote-fs.target nss-lookup.target network.service mysql.service

vi /lib/systemd/system/crond.service
  [Unit]
  Description=Command Scheduler
  After=syslog.target auditd.service systemd-user-sessions.service time-sync.target network.service mysql.service

Khi khởi động với ở trên tôi nhận được các lỗi tương tự. Tôi cũng nhận được email trong mailqkhi mạng / DNS chưa sẵn sàng khi xử lý tập lệnh cron. Một vài phút sau khi khởi động, chúng được gửi chính xác.

Bất cứ ai cũng có thể giúp có được quyền này bằng cách đảm bảo các dịch vụ được sa thải theo đúng thứ tự? Có vẻ như rất sai khi nó khởi động quá nhanh và lý tưởng là nó đã làm theo cách cũ, "khởi chạy một serice ... chờ đợi ... tung ra một dịch vụ mới ... chờ đợi ... vân vân).

Xin lưu ý rằng tôi không chắc đó là systemdvấn đề của tôi - đó chỉ là lý thuyết của tôi về những gì tôi có thể đọc từ mạng.


Bạn có thể gửi đầu ra của grep -i concurrency /etc/default/rcS? Tôi có thể trộn lẫn các hệ thống init của mình nhưng dường như tôi nhớ lại rằng điều khiển xem các tiến trình có chờ đợi nhau kết thúc hay không.
terdon

Tôi không có tập tin với/etc/default/rc*
DHS

Xin lỗi, tôi không biết tương đương với CentOS. Tôi đã nghĩ về những gì được mô tả ở đây cho Debian, điều này làm cho các dịch vụ bắt đầu song song. Có thể có một cái gì đó tương tự được thiết lập trong trường hợp của bạn.
terdon

2
Hãy thử thêm Requires=network.targetvào các đơn vị ở trên.
casey

Vẫn còn vấn đề tương tự sau khi được chèn Requires=network.targetvào/lib/systemd/system/crond.service
DHS

Câu trả lời:


9

Sau khi đọc nhiều hơn, tôi tìm thấy giải pháp phù hợp với mình.

Tôi đọc hướng dẫn này, Dịch vụ đang chạy sau khi Mạng kết thúc . Một trích dẫn nhỏ từ hướng dẫn:

Điều này sẽ đảm bảo rằng tất cả các thiết bị mạng được cấu hình đều hoạt động và có địa chỉ IP được gán trước khi tiếp tục khởi động.

Đây chính xác là những gì tôi muốn vì vậy tôi đã kích hoạt dịch vụ này và đặt quy tắc phụ thuộc trong tệp dịch vụ cho crond:

[root@srv]# systemctl enable NetworkManager-wait-online

[root@srv]# vi /lib/systemd/system/crond.service
  Requires=network.target
  After=syslog.target auditd.service systemd-user-sessions.service time-sync.target network.target mysqld.service

Như mysqldvẫn dựa trên cái cũ init.dtôi cần để tạo một systemddịch vụ như được đề xuất ở đây, systemctl cho phép khác với systemctl start :

[root@srv]# vi /lib/systemd/system/mysqld.service
  [Unit]
  Description=MySQL Server
  After=network.target
  [Service]
  Type=forking
  ExecStart=/etc/rc.d/init.d/mysql start
  ExecStop=/etc/rc.d/init.d/mysql stop
  [Install]
  WantedBy=multi-user.target

[root@srv]# systemctl daemon-reload
[root@srv]# chkconfig mysql off
[root@srv]# systemctl enable mysqld

Và cuối cùng thiết lập dịch vụ Apache để khởi động sau MySQL:

[root@srv]# vi /lib/systemd/system/httpd.service
  Requires=mysqld.service
  After=network.target remote-fs.target nss-lookup.target mysqld.service

Điều này làm việc cho tôi ít nhất.

Tôi đã sử dụng các lệnh này để kiểm tra nó sau đó, nơi tôi có thể thấy rõ rằng mạng được khởi động trước ít nhất là MySQL và Apache. Tôi mặc dù không thể nhìn thấy crondbất cứ nơi nào nhưng tôi có thể thấy nó đang hoạt động trong các tập lệnh của mình:

[root@srv]# systemd-analyze critical-chain
  multi-user.target @10.510s
    + httpd.service @10.344s +165ms
      + mysqld.service @9.277s +1.065s
        + network.target @9.273s
          + network.service @8.917s +355ms
            + iptables.service @444ms +157ms
              + basic.target @443ms
                [CUT]

Một vài lệnh hữu ích khác mà tôi đã sử dụng là:

# See exactly what takes how long (who to blame for the delay)
[root@srv]# systemd-analyze blame

# Check available names that can be used in the service files
[root@srv]# systemctl list-unit-files

Nếu bất kỳ ai có thể thấy bất kỳ cách nào tốt hơn để làm điều này thì xin vui lòng chia sẻ.


+1 để đăng các lệnh bạn đã sử dụng để gỡ lỗi này. Tôi đã có thể giải quyết một vấn đề thực sự khó chịu với systemd-analyze critical-chain. Tôi không chỉ sử dụng nó thường xuyên, mà tôi còn bất ngờ được bán systemd. Cảm ơn!
Brian đứng đầu

Bạn không nên sửa đổi các tệp dịch vụ được quản lý bởi người quản lý gói phân phối của bạn. Thay vào đó, bạn nên sử dụng các tệp cấu hình thả xuống tốt hơn. Xem câu trả lời cho Làm cách nào để ghi đè hoặc định cấu hình dịch vụ systemd?
Ludovic Ronsin
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.