$walker
Linux · 运维

Linux 实现指定服务开机自启

在 CentOS 上用 sh 脚本 + chkconfig 把一个 Java 服务注册为系统服务并设置开机自启,附 init.d 脚本模板、运行级别说明与常见坑。

发表于 2017-11-09约 3 分钟更新于 2023-08-01Linux运维

本教程介绍在 CentOS 服务器上实现指定服务开机自启。整体分四步:写启动脚本 → 注册成系统服务 → 设置开机自启 → 排查常见问题。

一、用 sh 脚本启动服务

vim itService-start.sh

脚本内容如下:

#!/bin/sh

# cd 到脚本所在的目录,并把路径赋值给 DIR
DIR=$(cd "$(dirname "$0")" && pwd)

# 把要运行的 jar 包赋值给 classPath
classPath=$DIR/itservice-0.1.jar

# 把主函数入口赋值给 mainClass
mainClass=s.com.wkh.ItService

# 把启动脚本日志赋值给 shLogPath
shLogPath=$DIR/sh_start.log

# 获取该服务的进程号并强制结束进程
jps | grep ItService | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1

# 后台运行 jar 包
nohup java -cp "$classPath" "$mainClass" >"$shLogPath" &

# 显示当前所有 java 进程 pid
jps

至此就可以用 itService-start.sh 启动该服务了。

二、注册成一个系统服务

服务脚本必须存放在 /etc/init.d/ 目录下:

vim /etc/init.d/itservice

脚本内容如下:

#!/bin/sh

### BEGIN INIT INFO
# Provides:          itservice
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Description:       itservice
### END INIT INFO

RETVAL=0

tdir=/root/itService

pidof=`jps | grep ItService | awk '{print $1}'`

case "$1" in
  start)
    if [ -z "$pidof" ]; then
      echo "Starting ItService..."
      $tdir/itService-start.sh
    else
      echo "ItService already running"
    fi
    RETVAL=$?
    ;;

  stop)
    echo "Stopping ItService..."
    [ -z "$pidof" ] && echo "ItService not running..." || kill $pidof
    RETVAL=$?
    ;;

  restart)
    echo "Stopping ItService..."
    echo "Starting ItService..."
    $tdir/itService-start.sh
    RETVAL=$?
    ;;

  status)
    [ -z "$pidof" ] && echo "ItService not running..." || echo "ItService running with pid $pidof"
    RETVAL=$?
    ;;

  *)
    echo "Usage: /etc/init.d/itservice {start|stop|restart|status}"
    RETVAL=$?
    ;;
esac

exit $RETVAL

至此脚本写完,用 chkconfig --add itservice 注册成一个系统服务。此时服务会在 /etc/rc.d/rcN.d 中被赋予 K/S 入口,然后就可以用 service itservice start 来启动了。

三、用 chkconfig 设置开机自启

chkconfig --level 35 itservice on

--level <等级代号> 指定该服务要在哪一个执行等级中开启或关闭。

等级 含义
0 关机
1 单用户模式
2 无网络连接的多用户命令行模式
3 有网络连接的多用户命令行模式
4 不可用
5 带图形界面的多用户模式
6 重新启动

四、常见问题

  1. sh 没有执行权限

    chmod 700 itService-start.sh
  2. chkconfig --add servicename 时提示 service xxx does not support chkconfig

    必须把下面两行注释放在 /etc/init.d/itservice 文件靠前的注释中:

    # Default-Start:    2 3 4 5
    # Default-Stop:     0 1 6

PS:不在脚本所在目录执行 sh 时要注意工作目录的问题。

补充:CentOS 7 及以上推荐用 systemd

上面是 SysVinit 时代的做法。CentOS 7 起默认使用 systemd,虽然仍兼容 chkconfig,但更推荐写一个 unit 文件,好处是自带日志(journalctl)、自动重启和依赖管理:

# /etc/systemd/system/itservice.service
[Unit]
Description=ItService
After=network.target

[Service]
Type=simple
WorkingDirectory=/root/itService
ExecStart=/usr/bin/java -cp /root/itService/itservice-0.1.jar s.com.wkh.ItService
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

然后执行:

systemctl daemon-reload
systemctl enable --now itservice   # 设置开机自启并立即启动
systemctl status itservice         # 查看状态
journalctl -u itservice -f         # 跟踪日志