如何让这个 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_6379
。 status
参数由命令 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。同样,请务必编辑
conf
和 install
以适合您。大多数人可能希望删除侦听文件路径以支持 TCP 堆栈,并为客户端打开 redis 端口号,
【讨论】:
以上是关于如何让这个 init.d 脚本在服务器重新启动时启动?的主要内容,如果未能解决你的问题,请参考以下文章
具有嵌入式 init.d 脚本的 Spring Boot 应用程序未在重新启动时启动