CentOS 7的启动速度太快,并且在执行cron脚本时网络还没有准备好


9

我刚刚从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我的问题-这只是我从网上可以读取的内容的理论。


您可以发布的输出grep -i concurrency /etc/default/rcS吗?我可能会混合使用我的init系统,但我似乎还记得,它控制着进程是否彼此等待完成。
terdon

我没有使用的文件/etc/default/rc*
DHS

抱歉,我不知道CentOS等效版本在哪里。我在想这里为Debian 做的描述,它使服务并行启动。您的情况可能有类似的设置。
terdon

2
尝试添加Requires=network.target到上述单位。
casey 2014年

插入后仍有同样的问题Requires=network.target/lib/systemd/system/crond.service
国土安全部

Answers:


10

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

我阅读了本指南,“网络启动后运行服务”。指南中的一句话:

这将确保在继续引导之前,所有已配置的网络设备均已启动并分配了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

如果有人可以看到更好的方法,请分享。


+1用于发布您用于调试此命令的命令。我能够解决麻烦的问题systemd-analyze critical-chain。我不仅会经常使用它,而且突然被卖了systemd。谢谢!
布莱恩·托平

您不应修改由分发程序包管理器管理的服务文件。相反,您最好使用嵌入式配置文件。请参阅“ 如何覆盖或配置systemd服务?”
Ludovic Ronsin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.