Tengo 4 contenedores (aplicación Java) en 4 hosts docker. necesitan leer/escribir en el mismo archivo.
el bloqueo de archivos no se puede utilizar debido a un sistema operativo diferente.
Entonces, traté de crear un archivo .lock, si uno de los 4 contenedores creó el archivo .lock, los otros contenedores tendrán que esperar. Pero esto todavía no está funcionando bien. Los otros contenedores no pueden ver el archivo .lock creado por otros contenedores a veces (no en tiempo real).
¿Hay otras soluciones?
Te sugiero que reconsideres tus suposiciones:
La forma limpia de hacer esto es escribir un servidor muy básico (si la carga lo permite, esto puede ser nginx+PHP y se puede hacer en 10 minutos) que escribe el archivo, ejecutarlo en otro contenedor y conectarse a él desde el otros contenedores. Esto te dará:
Pruebe File lock api para implementar esto. Demostración en 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 aa 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()); } }