CentOS 7 melakukan booting terlalu cepat dan jaringan tidak siap ketika menjalankan skrip cron

9

Saya baru saja memutakhirkan dari CentOS 6.5 ke 7.0 dan saya tidak terlalu senang karena yang baru systemdmungkin memberi saya masalah. Sepertinya itu hanya boot terlalu cepat, memulai proses secara tidak sinkron dan mengacaukan dependensi layanan.

Misalnya saya memiliki beberapa pengaturan skrip crondyang dipicu setelah reboot:

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

Ini menghasilkan semua jenis kesalahan aneh (hanya menunjukkan salah satunya):

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)

Di atas saya menulis ke soket TCP. Cukup jelas bagi saya bahwa cronddimulai sebelum jaringan diinisialisasi dengan benar sebagai network is unreachable.

Hal yang sama berlaku dengan Apache dan MySQL (MariaDB). MySQL cukup lambat untuk startup (banyak data) yang berarti bahwa baik Apache dan banyak crondskrip startup saya gagal karena database MySQL tidak berjalan ketika skrip dipanggil.

Saya telah mencoba mengatur dependensi tetapi tidak berhasil; Saya telah menambahkan networkdan mysqllayanan ke [Unit](seperti yang terlihat dengan systemctl list-dependencies). Idealnya semua layanan menunggu hingga MySQL aktif dan berjalan:

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

Saat boot dengan yang di atas saya mendapatkan kesalahan yang sama. Saya juga menerima surel mailqkarena jaringan / DNS tidak siap ketika memproses skrip-skrip. Beberapa menit setelah startup mereka dikirim dengan benar.

Adakah yang bisa membantu memperbaiki ini dengan memastikan layanan dipecat dalam urutan yang benar? Tampaknya sangat salah bahwa ini adalah boot yang sangat cepat dan idealnya melakukannya dengan cara lama yang baik, "meluncurkan satu serice ... tunggu ... meluncurkan layanan baru ... tunggu ... seterusnya).

Perhatikan bahwa saya tidak yakin itu adalah systemdmasalah saya - itu hanya teori saya tentang apa yang bisa saya baca dari internet.

DHS
sumber
Bisakah Anda memposting output grep -i concurrency /etc/default/rcS? Saya mungkin mencampur sistem init saya, tetapi saya sepertinya ingat bahwa mengontrol apakah proses menunggu satu sama lain untuk menyelesaikan.
terdon
Saya tidak punya file dengan/etc/default/rc*
DHS
Maaf, saya tidak tahu di mana akan setara dengan CentOS. Saya sedang memikirkan apa yang dijelaskan di sini untuk Debian, yang membuat layanan dimulai secara paralel. Mungkin ada set yang serupa dalam kasus Anda.
terdon
2
Coba tambahkan Requires=network.targetke unit di atas.
Casey
Masih masalah yang sama setelah dimasukkan Requires=network.targetke/lib/systemd/system/crond.service
DHS

Jawaban:

9

Setelah lebih banyak membaca saya menemukan solusi yang cocok untuk saya.

Saya membaca panduan ini, Menjalankan Layanan Setelah Jaringan menyala . Kutipan kecil dari panduan ini:

Ini akan memastikan bahwa semua perangkat jaringan yang dikonfigurasi sudah di atas dan memiliki alamat IP yang ditetapkan sebelum boot dilanjutkan.

Inilah yang saya inginkan jadi saya mengaktifkan layanan ini dan menetapkan aturan dependensi dalam file layanan untuk 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

Karena mysqldmasih didasarkan pada yang lama init.dsaya perlu membuat systemdlayanan seperti yang disarankan di sini, systemctl memungkinkan berbeda dari systemctl mulai :

[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

Dan akhirnya setup layanan Apache untuk startup setelah MySQL:

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

Setidaknya ini bekerja untuk saya.

Saya telah menggunakan perintah ini untuk memeriksanya setelah itu di mana saya dapat dengan jelas melihat bahwa jaringan dijalankan sebelum setidaknya MySQL dan Apache. Meskipun saya tidak bisa melihat di crondmana saja tetapi saya bisa melihatnya berfungsi di skrip saya:

[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]

Beberapa perintah berguna lainnya yang saya gunakan adalah:

# 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

Jika ada yang bisa melihat cara yang lebih baik untuk melakukan ini maka silakan bagikan.

DHS
sumber
+1 untuk memposting perintah yang Anda gunakan untuk men-debug ini. Saya bisa menyelesaikan masalah yang sangat buruk systemd-analyze critical-chain. Saya tidak hanya akan sering menggunakannya, tetapi tiba-tiba saya dijual systemd. Terima kasih!
Brian Topping
Anda tidak boleh memodifikasi file layanan yang dikelola oleh manajer paket distribusi Anda. Sebagai gantinya Anda sebaiknya menggunakan file konfigurasi drop-in. Lihat jawaban untuk Bagaimana cara mengganti atau mengkonfigurasi layanan systemd?
Ludovic Ronsin