Ami*_*t G 6 java nfs file-locking
以下代码片段导致JVM崩溃:如果获取锁定后发生网络中断
while (true) {
//file shared over nfs
String filename = "/home/amit/mount/lock/aLock.txt";
RandomAccessFile file = new RandomAccessFile(filename, "rws");
System.out.println("file opened");
FileLock fileLock = file.getChannel().tryLock();
if (fileLock != null) {
System.out.println("lock acquired");
} else {
System.out.println("lock not acquired");
}
try {
//wait for 15 sec
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("closing filelock");
fileLock.close();
System.out.println("closing file");
file.close();
}
Run Code Online (Sandbox Code Playgroud)
观察:JVM接收KILL(9)信号并退出,退出代码为137(128 + 9).
可能在网络连接重建之后,文件描述符表中出现了问题.使用系统调用flock(2)和shell实用程序flock(1)可以重现此行为.
任何建议/解决方案?
PS:将Oracle JDK 1.7.0_25与NFSv4一起使用
编辑:此锁定将用于标识分布式高可用性集群中哪个进程处于活动状态.退出代码是137.我期待什么?检测问题的方法.关闭文件并尝试重新获取.
退出代码138没有暗示SIGKILL - 这是信号10,可以是SIGBUS(在solaris上)或SIGUSR1(在linux上).不幸的是,你没有告诉我们你正在使用哪一个.
从理论上讲,nfs应该透明地处理所有事情 - 机器崩溃,重新启动并清除锁.在实践中,我从来没有在NFS3中看到过这种工作,而NFS4(你正在使用它)使事情变得更加困难,因为没有单独的lockd()和statd().
我建议你在java进程上运行truss(solaris)或strace(linux),然后拔出网络插件,找出真正发生的事情.但说实话,只要我使用Unix(超过25年),人们就建议不要锁定NFS文件系统,我强烈建议你编写一个小型服务器程序来处理"谁做了什么"事情.让您的客户端连接到服务器,让他们向服务器发送一些"以X开头"和"停止执行X"消息,如果客户端的回答不超过,请让服务器正常超时连接. 5分钟.我99%肯定这会比你尝试修复NFS锁定花费更少的时间.
NFS 服务器重新启动后,所有具有活动文件锁的客户端都会启动锁回收过程,该过程的持续时间不超过所谓的“宽限期”(只是一个常量)。如果回收过程在宽限期内失败,NFS 客户端(通常是内核空间野兽)将 SIGUSR1 发送到无法恢复其锁定的进程。这就是你问题的根源。
当服务器端锁定成功后,客户端系统上的 rpc.lockd 会请求另一个守护进程 rpc.statd 来监视实现锁定的 NFS 服务器。如果服务器发生故障然后恢复,rpc.statd 将收到通知。然后它尝试重新建立所有活动锁。如果 NFS 服务器发生故障并恢复,并且 rpc.lockd 无法重新建立锁定,它会向请求锁定的进程发送一个信号 (SIGUSR1)。
http://menehune.opt.wfu.edu/Kokua/More_SGI/007-2478-010/sgi_html/ch07.html
您可能想知道如何避免这种情况。嗯,有几种方法,但没有一种是理想的: