这是场景:我有一个在 servlet 容器内运行的多线程 Java Web 应用程序。该应用程序在 servlet 容器内多次部署。有多个 servlet 容器在不同的服务器上运行。
也许这张图清楚地表明:
server1
+- servlet container
+- application1
| +- thread1
| +- thread2
+- application2
+- thread1
+- thread2
server2
+- servlet container
+- application1
| +- thread1
| +- thread2
+- application2
+- thread1
+- thread2
网络共享目录中有一个文件,所有这些线程都可以访问。他们确实经常访问该文件。大多数情况下,文件仅由这些线程读取。但有时会写出来。
我需要一个故障安全解决方案来同步所有这些线程,以保证数据一致性。
不起作用(正确)的解决方案:
使用 java.nio.channels.FileLock
我可以使用 FileLock 类同步来自不同服务器的线程。但这不适用于同一进程(servlet 容器)内的线程,因为文件锁在进程范围内可用。使用单独的文件进行同步,
我可以创建一个单独的文件,指示进程正在读取或写入文件。此解决方案适用于所有线程,但有几个缺点:- 表现。创建、删除和检查文件是相当慢的操作。具有一个同步文件的低权重实现将阻止文件的并行读取。
- 在需要手动清理的 JVM 崩溃后,同步文件将保留。
- 我们已经在删除网络文件系统上的文件时遇到了奇怪的问题。
使用消息传递
我们可以实现一个消息传递系统,线程将使用它来协调文件访问。但这对于这个问题来说似乎太复杂了。再说一遍:性能会很差。
有什么想法吗?