簡體   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