简体   繁体   中英

How to get this init.d script to start at server restart?

I'm following the directions on installing Redis on a production machine (CentOS using chkconfig).

The example script I was given requires the argument start to actually start it, which it seems init.d does not do (pass arguments).

The real command that must be run is /etc/init.d/redis_6379 start , but what its actually calling is /etc/inti.d/redis_6379 , which simply says use start or stop as an argument

Therefor, when my server reboots it doesnt actually start redis. What should I do here?

Here is the initial config

#!/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

Make sure your script is added for service management by chkconfig . Use chkconfig --list to see the list and use chkconfig --add scriptname if it's not there. After that configure the runlevels you want it to be called into. I would guess it's 3, 4 and 5 so: chkconfig --level 345 scriptname on .

You should tell us how exactly you are running the script from init.d

But here is a dirty workaround:

Change the line

start)

to

start|'')

This will make it start if there are no parameters passed.

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

Centos redis has an init script with a chkconfig header line stating that it will start in all runlevels, which is very bad. chkconfig is used to manage the symlinks in /etc/rc.d

# chkconfig:   - 85 15

I suggest that redis is a service to run in level 3 after critical services have launched (sshd for instance). In your test scenario's reboot your server before going to production. If redis cannot launch (just happened here) you cannot boot it in another runlevel to fix it.

If you implement the proper headers you can use init and also systemd (Fedora)

Your should add code below to the script /etc/inti.d/redis_6379 . The status argument is used by command service --status-all .

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

...

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

Init.d's days are numbered, wtf are you still reading this for? There's no more sudo service , all the new kids are slapping down syscrtl

Nowadays like of course on my ubuntu 17.04 server at work, /etc/rc.local didn't even exist

Just write a new one!

rc.local is awesome, especially combined with the unix style daemonize program ... those two alone, I can pretty much call it a day.

However, if you want to take rc.local to the next level, I'll cover basic ideas behind my own personal redis init.d script--same one we use on production servers across my company:

  1. pre-empt redis complaint about system socket/file limits

  2. slap in some linux perf and mess around with sysconf in persistent fashion

  3. autopilot redis while i go take a nap

#!/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

next, if we're doin' it right:

  1. let's have nice idiomatic case $money numbers, focused on starting and stopping without sorting through excessive PID tracking shenanigans

  2. take advantage of the start-stop-daemon (ie can't get cut short by parent process death if there is no parent process)

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. edit redis.conf to designate daemonize yes . Make redis the primary responsible party for administrative PID file state (in case you were wondering why we didn't have to do anything with it in the script, except read from it if it's around)
mkdir /etc/redis
echo 'daemonize yes' >> /etc/redis/redis.conf
echo 'pidfile /var/run/redis.pid' >> /etc/redis/redis.conf
  1. update your rc entry by name after copying and setting execution bits:
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. Here's the full example link w/ service installer. Again, be sure to edit conf and install to suit you. Most people would probably want to remove the listening file path in favor of TCP stack w/ redis port number open for client(s),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM