欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-16 11:24:49
...
业务场景

       应用程序之间以文件作为接口,为了简化设计,没有采用单独的文件传输模块,而是采用共用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..."