【问题标题】:How to get this init.d script to start at server restart?如何让这个 init.d 脚本在服务器重新启动时启动?
【发布时间】: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 是否已添加为[+]。如果是,那么即使在重新启动后它也可以工作。

标签: linux bash shell redis centos


【解决方案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 脚本背后的基本思想——我们在整个公司的生产服务器上使用的脚本相同:

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

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

          3. 我去打盹时自动驾驶 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
          

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

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

          2. 利用 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
          
          1. 编辑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
          
          1. 复制和设置执行位后按名称更新您的 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
          
          1. 这是带有服务安装程序的full example link。同样,请务必编辑 confinstall 以适合您。大多数人可能希望删除侦听文件路径以支持 TCP 堆栈,并为客户端打开 redis 端口号,

          【讨论】:

            猜你喜欢
            • 2022-01-20
            • 2014-04-13
            • 1970-01-01
            • 2013-12-12
            • 2019-08-23
            • 1970-01-01
            • 2021-03-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多