Linux NFS上的Java FileLock问题

0 人关注

我在一台Linux服务器机器上使用Java的文件锁定API,并试图在一个远程Linux NFS系统上锁定一个文件。有一些问题冒出来了,日志显示 2 different cluster nodes 运行相同的Java Webserver应用程序,能够 both 获得同一NFS文件的锁。

在网上阅读关于Java如何处理锁和Linux文件锁(我们通常在Windows服务器上部署,所以很少有Linux经验),我们所做的是 should 工作。我们基本上是在发布 咨询 但由于两个集群节点运行相同的代码,它们是合作的进程,在开始做任何读写操作之前,它们会检查锁的获取情况。然而,情况似乎并非如此,两个系统都能成功地获取文件上的锁,而且是同时进行。

这些是已知的问题吗?网上的许多评论/文章宣称NFS文件锁是不稳定的,应避免使用。这是为什么呢?网络连接问题(例如,突然的通信中断)会如何影响这种行为?Linux内核版本应该是相当新的。

5 个评论
你使用的是哪个版本的NFS协议? NFS 2和3不支持锁定。 你在使用什么NFS挂载选项? (在受影响的NFS客户节点上。)
这不会是Java的 "错"。 Java只是在使用操作系统提供的锁定系统调用。 问题将出现在客户端操作系统、远程文件系统的挂载方式和/或NFS服务器的设置方式。
@StephenC 我们应该寻找哪些选项,应该配置哪些值,以实现预期的功能?同时将要求我们的客户向我们提供他们使用的NFS版本和NFS挂载选项。
They should require NFS 4 and (obviously) not use the nolock option. But I don't know if that is sufficient. Since it is not a programming question, this question should be asked on a different SE site. Maybe "ServerFault" or "UNIX & Linux" ... where people whose skills are in this areas. And search for answers there too.
我认为你的评论包含了我们需要的缺失的线索。 请看我的答案。
java
linux
nfs
file-locking
PentaKon
PentaKon
发布于 2022-08-08
2 个回答
Stephen C
Stephen C
发布于 2022-09-01
已采纳
0 人赞同

@StephenC 经过一些测试,当从java主方法中调用 RandomAccessFile.getChannel().tryLock() 时,在nfs4上运行正常,但当同样的代码在Tomcat(8.5.68)中运行时,会出现多锁。

好的。 所以我想我现在明白了你问题的根源。 从你所说的情况来看,它 sounds to me 就像你试图使用 FileLock 来阻止Tomcat JVM的一个线程锁定一个文件的某个部分,而另一个Tomcat线程则锁定了它。

这是不可能的。

你所使用的锁是一个 FileLock 。的一个关键段落。 javadoc 指出这一点。

文件锁是代表整个Java虚拟机持有的。 它们不适合控制同一虚拟机内多个线程对一个文件的访问。 .

在这种情况下,"不适合 "意味着 "不工作"。

如果你深入到Linux手册中的 flock (2) (Java用它来实现这些锁)的页面,你会看到语义是以多进程而不是多线程来定义的。 比如说。

【替换代码4放置一个排他性的锁。 只有 one process 可以在特定的时间为一个特定的文件持有一个共享锁。

如果有一个不兼容的锁被 flock() 持有,那么对 flock() 的调用可能会阻塞。 另一个过程 .

So, in summary, it is still not Java's fault. You are trying to use FileLock in a way that Java doesn't support ... 和 could not support, given how Linux (和 indeed POSIX) flock is specified.

(IMO,所有关于NFS的东西都是一个红鲱鱼。 上述问题不是由NFS引起的。 它的原因是 shows up on an NFS file system, is that NFS operations take longer 和 therefore 对同一文件进行重叠操作的时间窗口要大得多。 而如果你的客户的用例是 锤击 their NFS ...)

(But if I am wrong 和 NFS is implicated, then your "main vs Tomcat" observation is inexplicable. The JVM will not be doing file locking differently in those two cases: it will be using the same OpenJDK code in both cases. Furthermore, the JVM won't even be aware that it is talking to an NFS file system. You can take a look at the OpenJDK codebase if you don't believe me. It's not that hard ...)

  • How to lock file for another threads
  • Is FileLock in java safe across multiple threads within the same process or between different processes or both?
  • 和 so on.

    非常好的答案,但不适合我的情况。你漏掉了关于我有两个集群节点的部分(也许我应该加粗),也就是说,不同的服务器在运行同一个应用程序,即两个不同的JVM。
    我一直在追踪这个错误,但我认为问题出在我们的代码上。在运行一个小的测试Java应用程序时,通过Linux nfs4锁定工作正常,但当它在我们的应用程序中执行时,同样的代码就会失败。这意味着我们的应用程序做了一些事情,以某种方式解锁文件...
    PentaKon
    PentaKon
    发布于 2022-09-01
    0 人赞同

    我找到了这个问题的根本原因。看来,当两个不同的线程 同一个JVM的 上创建一个 RandomAccessFile 对象。 相同 文件,从一个线程调用 RandomAccessFile.close 释放其他线程的锁 .