【问题标题】:read/write to the same file from multiple docker containers从多个 docker 容器读取/写入同一个文件
【发布时间】:2019-10-17 13:25:03
【问题描述】:

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

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

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

还有其他解决方案吗?

【问题讨论】:

    标签: java docker volume file-locking


    【解决方案1】:

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

    • 如果您的容器不是 4 个而是 400 个怎么办?
    • 如果它们位于不共享文件系统的服务器上怎么办?

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

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

    【讨论】:

    • 那么服务器不可扩展?
    【解决方案2】:

    尝试使用 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());
        }
    
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2016-12-25
    • 2011-03-09
    • 1970-01-01
    相关资源
    最近更新 更多