#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 все еще были там, и все работало, но когда вы завершили работу своего приложения, эти временные файлы также были удалены.