nfs连接故障自动检测和恢复程序

业务场景

       应用程序之间以文件作为接口,为了简化设计,没有采用单独的文件传输模块,而是采用共用nfs服务器的方式由系统层面自动完成文件的上传下载.但是,在维护阶段却经常发生nfs无法连接的问题,导致应用程序io报错,影响到了业务的正常推进.

原因分析

       1>客户端维护人员不知道的情况下,nfs server所在的服务器进行了重新启动,导致原来的挂接点无法访问nfs server,需要重新mount

       2>nfs client端主机重新启动,没有自动mount或者mount失败,导致应用程序报错

       3>网络故障导致nfs连接不可用

采取的对策

       通过shell程序定时自动检测nfs mount的情况

程序实现

       平时手动确认nfs的时候,用的是df命令,如果nfs连接有问题,因为是同步IO,所以df会卡死到那里等待,直到nfs连接可用为止才会返回,所以这次程序实现上,也是通过df命令的执行情况来判断nfs是否正常,不过需要通过两个进程来实现,如果一个进程的话,一旦df命令卡死到那里,整个程序就卡到那里不动了,所以需要两个shell程序.

1.主shell程序

       调用子shell程序,让子shell程序在后台执行

       sleep 30秒,然后通过pid来检测子shell进程是否已经退出

        如果子进程还在,那么说明nfs连接出现异常,返回异常 exit 2,

                注意:这里没有kill子shell进程,如果nfs mount成功,df会成功返回,子进程会自动退出,当然也可以手动kill掉

        如果子进程不在,那么进一步执行df|grep命令看一下mount挂接点是否存在

        如果mount挂接点不存在,那么执行mount命令进行挂接

        如果mount成功,返回成功 exit 0

        如果mount失败,返回异常 exit 1

  

2.子shell程序

       把pid写入一个文件中

       执行df命令

主程序

#!/bin/sh

echo "checknfs.sh start..."

workdir="/home/wk"
mdirdown="/data/download"
mdirup="/data/upload"
remoteip=1.2.3.4
rcdown=0
rcup=0

cd $workdir
sh ./checkdf.sh&

sleep 30

pid=`cat checkdfpid.log`
echo "got checkdf.sh pid is:"$pid
ps -p $pid
if [ $? -ne 0 ];
then
    downcount=`df|grep $mdirdown|wc -l`
    upcount=`df|grep $mdirup|wc -l`
	if [ $downcount -ge 1 ] && [ $upcount -ge 1 ];
	then
        echo "checknfs.sh end normally..."
        exit 0
	else
	    if [ $downcount -lt 1 ];
		then
		    mount  $remoteip:$mdirdown  $mdirdown
			rcdown=$?
			
			if [ $rcdown -ne 0 ];
			then
	            echo "(mount fail) -> "$mdirdown
			fi
		fi
        
        if [ $upcount -lt 1 ];
		then
		    mount  $remoteip:$mdirup  $mdirup
			rcup=$?
			if [ $rcup -ne 0 ];
			then
    	        echo "(mount fail) -> "$mdirup
			fi
		fi		
        
		if [ $rcdown -eq 0 ] && [ $rcup -eq 0 ];
	    then
		    echo "checknfs.sh end normally(remounted)..."
		    exit 0
		else
		    echo "checknfs.sh end abnormally(mount fail)..."
		    exit 1
		fi
	fi
else
	echo "checknfs.sh end abnormally(df block)..."
	exit 2
fi

子程序

#!/bin/sh

echo "checkdf.sh start..."
echo 'checkdf pid:'$$
echo $$ > checkdfpid.log

df

echo "checkdf.sh end normally..."

猜你喜欢

转载自blogzhoubo.iteye.com/blog/2358637