使用rc.local文件
配置
chmod +x /etc/rc.d/rc.local
vi /etc/rc.d/rc.local
在rc.local最后面加上要启动的sh脚本,如:
/home/XXX.sh
说明
rc.local是一个在类Unix系统中常见的脚本文件,它通常用于在系统启动过程的最后阶段执行一些自定义的命令或脚本。
它在系统的运行级别(run level)达到多用户目标(multi-user.target)时执行。
顺序问题
在/etc/rc.d/rc.local文件中,如果有多行启动shell脚本的命令,这些脚本默认是按照它们在文件中出现的顺序线性启动的。rc.local文件中的命令是顺序执行的,每条命令在前一条命令完成后才开始执行。
如果您希望这些脚本并发启动,您需要在每个脚本启动命令后添加一个&符号,这样它们就会在后台运行:
#!/bin/bash
/home/user/script1.sh &
/home/user/script2.sh &
/home/user/script3.sh &
使用&符号后,所有脚本都将几乎同时启动,并且它们将在后台运行,不会阻塞后续脚本的启动。
如果您的shell脚本已经包含了一个命令来在后台运行进程(如使用nohup或&),那么在rc.local文件中调用该脚本时,您不需要再次添加&符号。
在rc.local文件中,如果某个shell脚本出错并卡住,如果该脚本不是以后台方式运行,后续脚本将无法执行,但不会影响centos7正常进入系统。
使用systemd服务
配置
vi /etc/systemd/system/XXX.service
添加下面内容:
[Unit]
Description=My Custom Script
[Service]
ExecStart=/home/XXX.sh
[Install]
WantedBy=multi-user.target
systemctl enable XXX.service
说明
systemd是一个强大的系统和服务管理器,它取代了传统的init系统,提供了一个更现代、更高效的方式来管理系统启动、服务、挂载点、网络接口和其它系统组件。
使用cron任务
配置
crontab -e
追加命令:
@reboot /home/XXX.sh
说明
cron是一个定时任务调度器,它允许用户在预定的时间自动执行命令或脚本。cron守护进程crond在系统启动时自动运行,并负责调度和管理这些任务。
延迟说明
为了避免该运行的服务需要依赖的其他服务还无启动,可以适当的加延迟,如:
@reboot sleep 60; /home/test.sh
或
@reboot (sleep 60; sh /home/test.sh)
顺序问题
在cron中,如果某个shell脚本(sh)出错并卡住,这不会直接影响后续的cron任务。cron任务是独立运行的,每个任务在不同的进程中执行,因此一个任务的失败不会阻止其他任务按计划运行。
cron任务执行通常是并发的,而不是顺序的。
执行顺序
说明
使用systemd服务比使用rc.local文件更快,而使用cron任务,由于cron的启动也是systemd,所以cron也比rc.local文件更快。
systemd > cron > rc.local
测试
编写一个记录时间的脚本,分别配置三种方式进行开始时间的记录。
脚本内容,time.sh:
#!/bin/bash
# 获取当前系统时间
current_time=$(date '+%Y-%m-%d %H:%M:%S.%N')
# 将当前时间写入到/home/time.txt文件中
echo "$current_time" >> /home/time.txt
记录结果,/home/time.txt:
service:2024-09-23 07:30:31.008583483
crontab:2024-09-23 07:30:31.319821284
rc:2024-09-23 07:30:32.640559528
可以看出,启动优先级和速度都是systemd(service)更快。
systemd是CentOS 7默认的系统和服务管理器,而service命令是一个向后兼容的接口,service命令是一个符号链接,它指向systemctl命令,用于兼容旧的SysV init脚本。当您使用service命令时,它实际上是在调用systemctl,这使得您能够以兼容旧系统的方式管理服务。
启动失败问题
查看日志,手动分析原因
如果是rc.local启动,可以查询系统日志:grep rc.local /var/log/messages
该方式如果实际脚本(程序)已经运行,则无看到错误信息,原因是程序自身启动失败。
环境变量问题
增加待执行程序的具体路径,如xxx.sh:
#!/bin/bash
nohup java -jar wvp-pro-2.7.0-03051114.jar >> /dev/null &
改为:
nohup /home/jdk/java -jar wvp-pro-2.7.0-03051114.jar >> /dev/null &
为了避免需要这情况,我们可以在rc.local文件最前面,增加source /etc/profile,把环境变量加载,就不需要增加待执行程序的具体路径了,具体原理查看:http://heawill.top/archives/centos7de-etc-profilejie-xi
配置文件问题
对于jar程序,可能同目录下,会有application.yml配置文件,然后脚本如下:
xxx.sh:
#!/bin/bash
nohup java -jar wvp-pro-2.7.0-03051114.jar >> /dev/null &
这样这个脚本如果直接在rc.local中写xxx.sh,这样是启动不了的,有三个问题,1需要补充jar命令的具体路径,2需要补充jar文件的具体路径,3需要跳转到具体路径下(写具体路径,其实就包含了2点了,第二点可以省略)。
修改xxx.sh:
#!/bin/bash
cd /home/ #跳转到待执行jar的目录(该目录也包含application.yml)
nohup /home/jdk/java -jar wvp-pro-2.7.0-03051114.jar >> /dev/null &
如果application.yml不是外置,那么xxx.sh可以这样写:
#!/bin/bash
nohup /home/jdk/java -jar /home/wvp-pro-2.7.0-03051114.jar >> /dev/null &
依赖程序问题
待开机启动的程序,依赖某个程序,依赖的程序启动慢,或者没启动
如某个java程序启动需要先启动mysql,但是mysql没写在启动脚本或启动慢,就会导致java启动失败,这种情况,可以在启动java的脚本增加睡眠延迟,如
#!/bin/bash
sleep 30 #增加睡眠延迟,根据实际mysql启动时间调整
cd /home/
nohup java -jar /home/wvp/wvp-pro-2.7.0-03051114.jar >> /dev/null &