如何让这个 init.d 脚本在服务器重新启动时启动?

Posted

技术标签:

【中文标题】如何让这个 init.d 脚本在服务器重新启动时启动?【英文标题】:How to get this init.d script to start at server restart? 【发布时间】:2013-09-11 21:48:00 【问题描述】:

我正在按照在生产机器上安装 Redis 的说明进行操作(CentOS 使用 chkconfig)。

给我的示例脚本需要参数 start 来实际启动它,而 init.d 似乎没有这样做(传递参数)。

必须运行的真正命令是/etc/init.d/redis_6379 start,但它实际调用的是/etc/inti.d/redis_6379,它只是说use start or stop as an argument

因此,当我的服务器重新启动时,它实际上并没有启动 redis。我应该在这里做什么?

这是初始配置

#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# 
# chkconfig:   - 85 15
# description:  Redis is a persistent key-value database
# processname: redis_6379

REDISPORT=6379
EXEC=/usr/local/bin/redis-server
CLIEXEC=/usr/local/bin/redis-cli

PIDFILE=/var/run/redis_$REDISPORT.pid
CONF="/etc/redis/$REDISPORT.conf"

case "$1" in
    start)
        if [ -f $PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed"
        else
                echo "Starting Redis server..."
                $EXEC $CONF
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running"
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
                $CLIEXEC -p $REDISPORT shutdown
                while [ -x /proc/$PID ]
                do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped"
        fi
        ;;
    *)
        echo "Please use start or stop as first argument"
        ;;
esac

【问题讨论】:

/etc/rc3.d 中的链接名称是什么?如果它以S 开头,我认为应该给它start 参数。 尝试service --status-all 并检查redis_6379 是否已添加为[+]。如果是,那么即使在重新启动后它也可以工作。 【参考方案1】:

确保chkconfig 为服务管理添加了您的脚本。使用chkconfig --list 查看列表,如果不存在则使用chkconfig --add scriptname。之后配置您希望调用它的运行级别。我猜是 3、4 和 5,所以:chkconfig --level 345 scriptname on

【讨论】:

【参考方案2】:

你应该告诉我们你是如何从 init.d 运行脚本的

但这是一个肮脏的解决方法:

换行

start)

start|'')

如果没有传递参数,这将使它启动。

【讨论】:

【参考方案3】:

如果您想通过命令行启动服务,您也可以添加/etc/rc.d/rc.local,而不是在 init.d 中创建服务文件。

【讨论】:

我不明白这个答案。你的意思是他应该把他的脚本(上面那个)添加到 /etc/rc.d/rc.local/ ...?【参考方案4】:

Centos redis 有一个带有 chkconfig 标题行的 init 脚本,说明它将在所有运行级别启动,这非常糟糕。 chkconfig 用于管理 /etc/rc.d 中的符号链接

# chkconfig:   - 85 15

我建议 redis 是一个在关键服务启动后运行在 3 级的服务(例如 sshd)。在您的测试场景中,在投入生产之前重新启动您的服务器。如果 redis 无法启动(刚刚发生在这里),您无法在另一个运行级别启动它来修复它。

如果你实现了正确的头文件,你可以使用 init 和 systemd (Fedora)

【讨论】:

【参考方案5】:

您应该将以下代码添加到脚本/etc/inti.d/redis_6379status 参数由命令 service --status-all 使用。

# processname: redis_6379
# Source function library.
. /etc/init.d/functions

...

case "$1" in
    status)
        status -p $PIDFILE redis
        script_result=$?
        ;;

【讨论】:

【参考方案6】:

Init.d 的日子已经屈指可数了,你还在看这个吗?没有了sudo service,所有新来的孩子都在拍syscrtl

现在当然在我工作的 ubuntu 17.04 服务器上,/etc/rc.local 甚至不存在

只写一个新的!

rc.local 很棒,尤其是结合 unix 风格 daemonize program...仅这两个,我几乎可以收工了。

但是,如果您想让rc.local 更上一层楼,我将介绍我自己的个人 redis init.d 脚本背后的基本思想——我们在整个公司的生产服务器上使用的脚本相同:

    关于系统套接字/文件限制的抢先 redis 投诉

    添加一些 linux 性能并以持久的方式弄乱 sysconf

    我去打盹时自动驾驶 redis

#!/bin/sh

### BEGIN INIT INFO
# Provides:           redis
# Required-Start:     $syslog
# Required-Stop:      $syslog
# Should-Start:       $all
# Should-Stop:        $all
# Default-Start:      2 3 4 5
# Default-Stop:       0 1 6
# X-Interactive:      true
# Short-Description:  start and stop redis
# Description:        persistent key-value db
### END INIT INFO

NAME=redis
PATH=/opt/bin:/opt/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
EXEC=/opt/sbin/redis-server
CLIEXEC=/opt/sbin/redis-cli
CONF=/etc/$NAME/$NAME.conf
PIDFILE=/var/run/$NAME.pid
SOCKET=/var/run/$NAME.sock
PERF=/tmp/redis.sysctl
KERNELPG=/sys/kernel/mm/transparent_hugepage/enabled

[ -x /opt/sbin/redis-server ] || exit 0

set -e

# tune system for better redis performance
if [ ! -f $PERF ]; then
  echo "tunning redis..." &>> $PERF
  echo never > $KERNELPG && cat $KERNELPG &>> $PERF
  sysctl -w net.core.somaxconn=65535 &>> $PERF
  sysctl -w vm.overcommit_memory=1 &>> $PERF
  echo "tuned." &>> $PERF && cat $PERF
fi

接下来,如果我们做得对的话:

    让我们有一个很好的惯用案例 $money 数字,专注于启动和停止,而不需要对过多的 PID 跟踪恶作剧进行排序

    利用 start-stop-daemon(即,如果没有父进程,则不会因父进程死亡而缩短)

case $1 in
  start)
    if [ ! -f $PIDFILE ]; then
      echo -n "Starting $NAME: "
      start-stop-daemon --start --pidfile $PIDFILE --exec $EXEC -- $CONF
      echo "waiting for redis db to start..."
      while [ ! -f $PIDFILE ]; do
        sleep 0.1;
      done
    fi
    PID=$(cat $PIDFILE)
    echo "running with pid: $PID"
    ;;
  stop)
    if [ ! -f $PIDFILE ]; then
      echo "redis is already stopped"
    else
      PID=$(cat $PIDFILE)
      echo -n "Stopping $NAME: "
      $CLIEXEC -s $SOCKET shutdown
      echo "waiting for shutdown..."
      while [ -x /proc/$PID ]; do
        sleep 0.1
      done
      echo "db stopped."
    fi
    ;;
  status)
    if [ -f $PIDFILE ]; then
      PID=$(cat $PIDFILE)
      echo "running with pid: $PID"
    else
      echo "stopped."
    fi
    ;;
  restart|force-reload)
    $0 stop && $0 start
    ;;
  *)
    echo "Argument \"$1\" not implemented."
    exit 2
    ;;
esac

exit 0
    编辑redis.conf 以指定daemonize yes。让 redis 成为管理 PID 文件状态的主要责任方(如果您想知道为什么我们不必在脚本中对它做任何事情,除非在它附近读取它)
mkdir /etc/redis
echo 'daemonize yes' >> /etc/redis/redis.conf
echo 'pidfile /var/run/redis.pid' >> /etc/redis/redis.conf
    复制和设置执行位后按名称更新您的 rc 条目:
mkdir /etc/redis
vim /etc/redis/redis # keep it traditional, no .sh extensions here
# saving buffers from root all damn day...
chmod a+x /etc/init.d/redis
update-rc.d redis defaults
    这是带有服务安装程序的full example link。同样,请务必编辑 confinstall 以适合您。大多数人可能希望删除侦听文件路径以支持 TCP 堆栈,并为客户端打开 redis 端口号,

【讨论】:

以上是关于如何让这个 init.d 脚本在服务器重新启动时启动?的主要内容,如果未能解决你的问题,请参考以下文章

如何让我的 init.d 脚本更改用户

使用 init.d 重新启动 Node.js 应用程序

具有嵌入式 init.d 脚本的 Spring Boot 应用程序未在重新启动时启动

如何让 Zabbix Server 和 Zabbix Agentd 开机自动运行

linux中/etc/init.d设置开机启动

在 Ubuntu 中调试 /etc/init.d 启动脚本