繁体   English   中英

从多个 docker 容器读/写同一个文件

[英]read/write to the same file from multiple docker containers

我在 4 个 docker 主机中有 4 个容器(java 应用程序)。 他们需要读/写同一个文件。

由于操作系统不同,无法使用文件锁。

因此,我尝试创建一个 .lock 文件,如果 4 个容器之一创建了 .lock 文件,则其他容器将不得不等待。 但这仍然不能很好地工作。 其他容器有时无法看到其他容器创建的 .lock 文件(不是实时的)。

还有其他解决方案吗?

我建议你重新考虑你的假设:

  • 如果您没有 4 个而是 400 个容器怎么办?
  • 如果他们在不共享文件系统的服务器上怎么办?

这样做的干净方法是编写一个非常基本的服务器(如果负载允许,这可以是 nginx+PHP,并在 10 分钟内完成)来执行文件写入,在另一个容器中运行它并从其他容器。 这会给你:

  • 文件锁定简单可靠,因为文件只能被一台服务器看到
  • 可扩展性
  • 集群性
  • 抽象

尝试 File lock api 来实现这一点。 用 Java 演示。

public void modifyFile() {

    try {
        File file = new File("/tmp/fileToLock.dat");

        // Creates a random access file stream to read from, and optionally to write to
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

        // Acquire an exclusive lock on this channel's file (blocks until lock can be retrieved)
        FileLock lock = null;

        // Attempts to acquire an exclusive lock on this channel's file (returns null or throws
        // an exception if the file is already locked.
        try {
            lock = channel.tryLock();
            if (null != lock) {
                List<String> fileToString = FileUtils.readLines(file, StandardCharsets.UTF_8);
                long l = 0l;
                if (null != fileToString && fileToString.size() > 0) {
                    l = Long.valueOf(fileToString.get(fileToString.size() - 1));
                }
                l++;
                FileUtils.writeStringToFile(file, String.valueOf(l) + "\r\n", StandardCharsets.UTF_8, true);
            }
        } catch (OverlappingFileLockException e) {
            // thrown when an attempt is made to acquire a lock on a a file that overlaps
            // a region already locked by the same JVM or when another thread is already
            // waiting to lock an overlapping region of the same file
            System.out.println("Overlapping File Lock Error: " + e.getMessage());
            channel.close();
        }

        // release the lock
        if (null != lock) {
            lock.release();
        }
        // close the channel
        channel.close();

    } catch (IOException e) {
        System.out.println("I/O Error: " + e.getMessage());
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM