Linux 遇到 kernel panic 后可自动重启

Linux自动重启服务,Linux重启服务

服务器不重启的情况下定时自动重启apache及mysql服务,其实也大同小异。具体步骤如下:
一、每天的12点及16点重启apache及mysql服务
[[email protected] bin]# cd /opt/
[[email protected] opt]# vim reboot.txt
在reboot.txt.txt文件中输入下面的内容后保存
0 12 * * * service httpd restart
0 12 * * * service mysqld restart
0 16 * * * service httpd restart
0 16 * * * service mysqld restart

二、把新建的文件加入到cron服务中
[[email protected] opt]# crontab reboot.txt
[[email protected] opt]# crontab -l
0 12 * * * service httpd restart
0 12 * * * service mysqld restart
0 16 * * * service httpd restart
0 16 * * * service mysqld restart

三、重启cron服务
[[email protected] opt]# /sbin/service crond restart

=======================================
补充说明:
cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置

时程表的基本格式 :
*  *  *  *  *  program
分  时  日  月  周        命令
第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令

当第1列 为 * 时表示每分钟都要执行 program,第2列为 * 时表示每小时都要执行程式,其余类推
当第1列为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,第2列为 a-b 时表示从第 a 到第 b 小时都要执行,其余类推
当第1列为 */n 时表示每 n 分钟个时间间隔执行一次,第2列 为 */n 表示每 n 小时个时间间隔执行一次,其余类推
当第1列为 a, b, c,… 时表示第 a, b, c,… 分钟要执行,第2列 为 a, b, c,… 时表示第 a, b, c…个小时要执行,其余类推

crontab文件的一些例子:
30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启lighttpd 。
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启lighttpd 。
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启lighttpd 。
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启lighttpd 。
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启lighttpd 。
* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启lighttpd
* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启lighttpd
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启lighttpd
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启lighttpd
 
如果需要重新启动服务器,加一行 0 12 * * * root init 6
 
做个记号,毕竟linux vi 编辑器下经常会用到保存退出与不保存退出这两个操作.
linux vi 保存退出 操作:esc键,输入      :wq
linux vi 不保存退出 操作:esc键,键入    :q!
 
在linux下使用VIM进行编程是一件很自然的事情
刚开始时我也对VI超多的指令和完全的放弃鼠标感到不适!
但经过了初期的适应性阶段,我终于放发现,原来放弃了鼠标却也提高了效率!

废话少说,进入正题:
“(TAB上边的点):回到光标跳转前的位置。
dd:删除一行。
5dd:删除光标处以下的五行。
按V键进入可视模式,选择要拷贝的内容,按yy拷贝选中的内容,在需要的地方按p拷贝内容到新光标处或新文件中。
i:进入插入模式。
v:进入可视模式。
Esc:回到基本模式
h,j,k,l:上下左右移动光标
vsp:左右分割窗口。
sp:上下分割窗口。
ctrl+w:在窗口中选择。
:q!:不保存退出。
x:保存退出。
w:只保存不退出。
x:删除一个字符。
u:撤消
CTRL+O:回跳。
CTRL+R:撤消刚才的撤消。
:help:帮助。
zz:退出帮助窗口。
3w :向前移动三个单词。
3b:向后移动三个单词。
CTRL+[:跳到光标单词处。
CTRL+T:跳回?
9k:上移九行。
:e 打开新文件(在多窗口操作中很有用)。
yaw:拷贝一个单词。
CTRL+B:把光标移到当前行的左边首部。
CTRL+E:把光标移到当前行的右边首部。
vim -r doc.txt:恢复文件到修改前。
:/查找单词
H:跳到第一行。
M:跳?中间。
L:跳到最后一行。
CTRL+d,u,f,b:下移半屏,上移半屏,下移一屏,上移一屏。
gg:到文件开始处
G:到文件尾部。
–:找到文件上次修改点。
CTRL+p,n:向上查询一?单词,向下查询一个单词。
zo:打开折叠。l键也可以。
zc:关闭折叠。
zr:全部打开折叠。
zm:全部关闭折叠。
zf:创建折叠。
zR:打开所有折叠(包括嵌套)
zM:关闭所有折叠(包括嵌套)
:!ls,查看目录表。
:`o,找到最后修改的文件。
wq,保存退出。
vim txt1 txt2 txt3 txt4,同时打开多个文件,
以下是同时打开多个文?时(建议用多窗口)
n,下一个文件,
n3,往下第三个文件。
first,第一个文件。
last,最后一个文件 。
:/s#kkk#ccc#g,把文件中的kkk替换为ccc

公司tomcat服务器有个过一段时间自动会挂的bug一直没能解决,挂的时候还要手动重启tomcat,于是决定写个脚本让它定时检测故障自动重启吧。

突然发现155服务器已经死机了,系统是Linux。现场察看6个硬盘已经有2个亮了故障告警灯。所幸是逻辑故障,今天已经排除。

现在的 Linux 比10年前要成熟的多,但有时候还是会出现莫名其妙、无法解释的
kernel panic 情况。对于大部分 Linux 用户来说出现 kernel panic
重启一下就可以了,但是对于系统管理员和那些做虚拟主机、共享主机、OpenVZ
VPS 主机的 hosting 服务商来说出现未知的 kernel
panic、导致系统挂掉可能就不太友好,如果没有 KVM over IP 的话,系统挂掉后
hosting 服务商需要自己先反馈到上一级的独立服务器提供商,比如提交 ticket
或者打电话,然后独立服务器供应商还要时间验证你的资料、处理你的
ticket,最后才到真正的数据中心,一般晚上(中国的白天)数据中心只有几个人值班,到最后处理完你的重启请求可能已经过了20多分钟了,这20分钟的
downtime
时间你还要给你自己的客户写信解释情况,问题是这20分钟还是理想情况,如果你碰到一个很烂的独立服务器提供商或数据中心,处理
ticket 要以小时或天为单位来计,或者如果你是 one
man、晚上正在睡觉没有收到 kernel panic
报警,这样的话花的时间就会更多。那么有没有办法让 Linux 服务器遇到 kernel
panic 情况自动重启呢?

Linux下监控程序并自动重启的方法分享

#!/bin/bash
if [ !  -f /tmp/down_count ];then
    echo "0" > /tmp/down_count
fi
curl -I  tomcat-host -o "/tmp/status" >/dev/null 2>&1
code=`awk 'NR==1 {print $2}' /tmp/status`
if [ "${code}" -ge 500 ];then
    down=`expr $(cat /tmp/down_count) + 1`
    echo "$down" > /tmp/down_count
    if [ "$down" -gt 3 ];then
        if [ ! -f "/tmp/restart_count" ];then
            echo "0" > /tmp/restart_count
        fi
        restart_count=`expr $(cat /tmp/restart_count) + 1`
        echo "$restart_count" > /tmp/restart_count
        if [ "$restart_count" -le 2 ];then
                /etc/init.d/tomcat6 restart
                echo "tomcat down at `date`" >> /tmp/down_info
        fi
    fi
else
    echo "0" > /tmp/down_count
    echo "0" > /tmp/restart_count
fi

服务器重启后,发现网页服务工作不正常。这是个老毛病了,每次重启服务器需要关闭httpd
-k stop,然后再打开httpd -k start,网页服务就会正常工作。

编辑 /etc/sysctl.conf 文件,并定义遇到 kernel panic 20秒后自动重启
Linux:

 

脚本实现了,当检测网页状态码大于等于500连续出现3次数,自动重启tomcat6,且只连续重启两次。

但是今天,我向服务器发出httpd命令,尽然不响应!-bash: httpd: command not
found。这个命令我已经使用了很久了,多次了!

# vi /etc/sysctl.conf kernel.panic = 20
Linux 这么神奇?遇到 kernel panic 自己都挂了还能自己重启?来看看 Linux
内核里面这部分代码是怎么工作的,最好最权威的资料永远来自内核源代码:

如果是简单的手机重启,可以按如下操作进行: 

经过了许多曲折,发现问题出在su。如果su转成root,操作环境继承了普通用户的环境,很多命令不可用。必须su
-转成root,才会完整地获得root的工作环境。

# vi linux-2.6.31.8/kernel/panic.c … if (panic_timeout > 0) { /*
* Delay timeout seconds before rebooting the machine. * We can’t use
the “normal” timers since we just panicked. */ printk(KERN_EMERG
“Rebooting in %d seconds..”, panic_timeout); for (i = 0; i <
panic_timeout*1000; ) { touch_nmi_watchdog(); i += panic_blink(i);
mdelay(1); i++; } /* * This will not be a clean reboot, with
everything * shutting down. But if there is a chance of * rebooting
the system it will be rebooted. */ emergency_restart(); } …

—-Linux 重启命令—- 

图片 1

图片 2

Java代码  

1、shutdown  

2、poweroff  

3、init  

4、reboot  

5、halt  

 

这里不作介绍了,主要是讲自动重启实现方法。 

 

使用脚本实现自动重启 

首先想到的最简单的使用shell脚本,大概思路: 

ps -ef | grep “$1″ | grep -v “grep” | wc –l 是获取 $1 ($1
代表进程的名字)的进程数,脚本根据进程数来决定下一步的操作。通过一个死循环,每隔
1 秒检查一次系统中的指定程序的进程数,这里也可使用crontab来实现。 

这种方法比较土,还是可以基本解决问题,但是有1s的延迟,笔者在应用中未采用这种方法,有关这个shell脚本,请参看文章后面的附件代码。 

exec+fork方式 

笔者最终采用的exec+fork方式来实现的,具体思想如下: 

1,exec函数把当前进程替换为一个新的进程,新进程由path或file参数指定。可以使用exec函数将程序的执行从一个程序切换到另一个程序; 

2,fork函数是创建一个新的进程,在进程表中创建一个新的表项,而创建者(即父进程)按原来的流程继续执行,子进程执行自己的控制流程; 

3,wait
当fork启动一个子进程时,子进程就有了它自己的生命周期并将独立运行,我们可以在父进程中调用wait函数让父进程等待子进程的结束; 

相信介绍到这里,读者已经能够想到解决方法了:1)首先使用fork系统调用,创建子进程,2)在子进程中使用exec函数,执行需要自动重启的程序,3)
在父进程中执行wait等待子进程的结束,然后重新创建一个新的子进程。 

使用方法: 

Java代码  

#./portmap 需要监控的程序的路径  

#args portmap 需要的参数  

$ ./supervisor ./portmap  args…..代码如下:  

/** 

 * 

 * supervisor  

 * 

 * author: liyangguang
([email protected]) 

 * 

 * date: 2011-01-21 21:04:01 

 * 

 * changes 

 * 1, execl to execv 

 */  

   

#include <stdio.h>  

#include <unistd.h>  

#include <errno.h>  

#include <string.h>  

#include <sys/types.h>  

#include <sys/wait.h>  

#include <stdlib.h>  

   

int  

main(int argc, char **argv)  

{  

    int ret, i, status;  

    char *child_argv[100] = {0};  

    pid_t pid;  

    if (argc < 2) {  

   

        fprintf(stderr, “Usage:%s <exe_path> <args…>n”,
argv[0]);  

        return -1;  

    }  

    for (i = 1; i < argc; ++i) {  

        child_argv[i-1] = (char *)malloc(strlen(argv[i])+1);  

        strncpy(child_argv[i-1], argv[i], strlen(argv[i]));  

        child_argv[i-1][strlen(argv[i])] = ”;  

    }  

    while(1){  

   

        pid = fork();   

        if (pid == -1) {  

            fprintf(stderr, “fork() error.errno:%d error:%sn”, errno,
strerror(errno));  

            break;  

        }  

        if (pid == 0) {  

            ret = execv(child_argv[0], (char **)child_argv);  

            //ret = execl(child_argv[0], “portmap”, NULL, 0);  

            if (ret < 0) {  

                fprintf(stderr, “execv ret:%d errno:%d error:%sn”, ret,
errno, strerror(errno));  

                continue;  

            }  

            exit(0);  

        }  

   

        if (pid > 0) {  

            pid = wait(&status);  

   

            fprintf(stdout, “wait return”);  

        }  

   

    }  

   

   

    return 0;  

}  

shell脚本方式的代码如下:  

 代码如下   复制代码  

# 函数: CheckProcess  

# 功能: 检查一个进程是否存在  

# 参数: $1 — 要检查的进程名称  

# 返回: 如果存在返回0, 否则返回1.  

#——————————————————————————
 

CheckProcess()  

{  

  # 检查输入的参数是否有效  

  if [ “$1” = “” ];  

  then  

    return 1  

  fi  

 

 

 
#$PROCESS_NUM获取指定进程名的数目,为1返回0,表示正常,不为1返回1,表示有错误,需要重新启动 

Java代码  

 PROCESS_NUM=`ps -ef | grep “$1” | grep -v “grep” | wc -l`   

  if [ $PROCESS_NUM -eq 1 ];  

  then  

    return 0  

  else  

    return 1  

  fi  

}  

   

   

# 检查test实例是否已经存在  

while [ 1 ] ; do  

 CheckProcess “test”  

 CheckQQ_RET=$?  

 if [ $CheckQQ_RET -eq 1 ];  

 then  

   

# 杀死所有test进程,可换任意你需要执行的操作  

   

   

  killall -9 test  

  exec ./test &    

 fi  

 sleep 1  

done  

如果是简单的手机重启,可以按如下操作进行: —-Linux 重启命令—-
Java代码 1、shutdown 2、poweroff 3、…

发表评论

电子邮件地址不会被公开。 必填项已用*标注