CentOS 7启动太快,执行cron脚本时网络未准备好

CentOS 7启动太快,执行cron脚本时网络未准备好

我刚刚从 CentOS 6.5 升级到 7.0,我不太高兴,因为新版本systemd可能会给我带来问题。看起来这只是启动太快,异步启动进程并搞乱了服务依赖性。

例如,我有一些脚本设置,crond其中在重新启动后触发:

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

这会导致各种奇怪的错误(仅显示其中之一):

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)

在上面我正在写入 TCP 套接字。我很清楚它crond是在网络正确初始化为network is unreachable.

Apache 和 MySQL (MariaDB) 也是如此。 MySQL 的启动速度相当慢(数据量很大),这意味着 Apache 和我的许多crond启动脚本都失败了,因为在调用脚本时 MySQL 数据库没有运行。

我尝试过设置依赖项,但没有成功;我已附加networkmysql服务[Unit](如 所示systemctl list-dependencies)。理想情况下,所有服务都会等到 MySQL 启动并运行:

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

当使用上述启动时,我遇到了同样的错误。我还收到了电子邮件,mailq因为在处理 cron 脚本时网络/DNS 尚未准备好。启动后几分钟,它们就会正确发送。

任何人都可以通过确保服务以正确的顺序启动来帮助解决这个问题吗?它的启动速度如此之快似乎是非常错误的,理想情况下它以良好的旧方式完成,“启动一项服务...等待...启动一项新服务...等待...等等)。

请注意,我不确定这是systemd我的问题 - 这只是我从网上读到的理论。

答案1

经过大量阅读后,我找到了适合我的解决方案。

我阅读了本指南,网络通后运行服务。指南中的一点引述:

这将确保所有配置的网络设备均已启动并在继续启动之前分配有 IP 地址。

这正是我想要的,因此我启用了此服务并在服务文件中设置了依赖关系规则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

由于mysqld仍然基于旧的,init.d我需要systemd按照此处的建议创建服务,systemctl enable 与 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

最后设置 Apache 服务启动MySQL:

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

这至少对我有用。

我随后使用这些命令进行了检查,可以清楚地看到网络至少先于 MySQL 和 Apache 启动。我虽然看不到crond任何地方,但我可以看到它在我的脚本中工作:

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

我使用的其他一些有用的命令是:

# 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

如果有人能看到更好的方法来做到这一点,请分享。

相关内容