Использование CRIU для приложений Java

#jvm #migration #restore #checkpointing

#jvm #миграция #восстановить #контрольная точка

Вопрос:

Итак, я хочу использовать CRIU для создания моментального снимка процесса JVM и восстановления его позже. Для этой цели я написал небольшую программу, которая не делает ничего, кроме печати счетчика каждую секунду:

 package some;

public class Fun {
    public static void main(String[] args) throws InterruptedException {
        for(int i = 0; i < Integer.valueOf(args[0]); i  ) {
            System.out.println("Counter: " i);
            Thread.sleep(1000);
        }       
    }   
}
  

Теперь, когда я запускаю программу $ java some.Fun 3000 , программа начинает показывать мне секунды, пока все хорошо.

Теперь, когда я хочу сохранить процесс с помощью criu, я $ ps -aux нахожу PID моего java-процесса (в данном случае 3503) и вызываю criu для него $ criu dump -t 3503 -o dump.log --shell-job . После этого терминал со счетчиком прекращает подсчет, печатает Killed и, похоже, завершает работу.

На данный момент в папке, в которую я вызвал criu, у меня есть несколько файлов дампа, которые я могу использовать для восстановления процесса $ criu restore -o dump.log --shell-job

Когда я это делаю, создается новый процесс с новым PID, и счетчик начинает отсчет с момента его остановки, как и должно быть. Приятно!

Однако, допустим, я завершаю процесс и пытаюсь использовать те же файлы дампа для восстановления процесса. Если я это сделаю, criu сразу же завершит работу с сообщением Aborted (core dumped) . То же самое произойдет, если я попытаюсь перенести файлы на другой компьютер с той же версией Java и попытаюсь запустить его там…

Теперь мой вопрос: так ли это должно быть? Должны ли мы иметь возможность восстановить состояние только один раз? Или я делаю что-то не так? Заранее благодарю вас!

Ответ №1:

Вам необходимо отключить функцию perfdata в JVM.

$ java -XX:-Использовать некоторые данные.Удовольствие 3000

Это приведет к подавлению создания /tmp/hsperfdata_userid каталогов.

Проблема возникает из-за того, что, когда CRIU проверяет дерево процессов, он сохраняет информацию для всех открытых файловых дескрипторов, а во время восстановления требуется, чтобы все файлы присутствовали (и имели одинаковый размер).

Когда вы впервые восстановили свое java-приложение, временные файлы hsperfdata все еще были там, и все работало, но когда вы завершили работу своего приложения, эти временные файлы также были удалены.