Сохранение состояния в Java - PullRequest
5 голосов
/ 24 февраля 2012

Широкий вопрос для обсуждения.Есть ли какие-либо библиотеки, которые позволяют мне сохранять состояние выполнения моего приложения в Java?

Например, у меня есть приложение, которое обрабатывает файлы, теперь приложение может быть вынуждено внезапно завершить работу в какой-то момент. Я хочухранить информацию о том, что все файлы были обработаны, а что нет, и на какой стадии была обработка для текущих процессов.

Есть ли уже какие-либо библиотеки, которые абстрагируют эту функциональность, или мне пришлось быреализовать это с нуля?

Ответы [ 5 ]

3 голосов
/ 24 февраля 2012

Похоже, что вы ищете сериализацию, которую можно выполнить с помощью Java Serialization API .

Вы можете написать еще меньше кода, если решите использовать известные библиотеки, такие как Apache Commons Lang и его класс SerializationUtils , который сам по себе построен на Java Serialization API.

Использование последней версии, сериализация / десериализация состояния вашего приложения в файл выполняется в несколько строк.

Единственное, что вам нужно сделать, это создать класс, содержащий состояние вашего приложения, давайте назовем его ...ApplicationState :-) Это может выглядеть так:

class ApplicationState {

 enum ProcessState {
  READ_DONE,
  PROCESSING_STARTED,
  PROCESSING_ENDED,
  ANOTHER_STATE;
 }

 private List<String> filesDone, filesToDo;
 private String currentlyProcessingFile;
 private ProcessState currentProcessState;
}

При такой структуре и использовании SerializationUtils сериализация выполняется следующим образом:

try {
      ApplicationState state = new ApplicationState();
      ...
      // File to serialize object to
      String fileName = "applicationState.ser";

      // New file output stream for the file
      FileOutputStream fos = new FileOutputStream(fileName);

      // Serialize String
      SerializationUtils.serialize(state, fos);
      fos.close();

      // Open FileInputStream to the file
      FileInputStream fis = new FileInputStream(fileName);

      // Deserialize and cast into String
      String ser = (String) SerializationUtils.deserialize(fis);
      System.out.println(ser);
      fis.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
2 голосов
/ 24 февраля 2012

Похоже, API предпочтений Java может быть хорошим вариантом для вас.Это может хранить пользовательские / системные настройки с минимальными усилиями с вашей стороны, и вы можете обновить / восстановить в любое время.http://docs.oracle.com/javase/1.4.2/docs/guide/lang/preferences.html

1 голос
/ 24 февраля 2012

Это довольно просто сделать с нуля. Вы могли бы следовать этому:

  1. Иметь БД (или просто файл), в которой хранится информация о ходе обработки. Что-то вроде:

     Id|fileName|status|metadata
    
  2. Как только вы начнете обрабатывать файл, сделайте запись в этой таблице. Отмечая статус как PROCESSING, вы можете сохранять промежуточные состояния, и, наконец, когда вы закончите, вы можете установить статус на DONE.

    Таким образом, при перезапуске вы будете знать, какие файлы обрабатываются; Каковы файлы, которые были in-citu, когда процесс остановился / потерпел крах. И (очевидно) с чего начать.

В крупной корпоративной среде, где приложения слабо связаны (и нет гарантии, будет ли приложение доступно или может произойти сбой), мы используем очередь сообщений, чтобы сделать что-то подобное для обеспечения надежной архитектуры.

0 голосов
/ 24 августа 2013
0 голосов
/ 24 февраля 2012

Существует почти слишком много способов упомянуть.Я бы выбрал вариант, который вы считаете самым простым.

Вы можете использовать;

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

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

Это работает, потому что данные частично управляются ОС, что означает, что она использует небольшую кучу (даже для ТБ данных), а ОС занимается загрузкой и сбросом на диск, делая их намного быстрее (и делая размеры намного больше, чем ваши основныепамять практическая).

Кстати: этот подход работает даже с kill -9, поскольку ОС сбрасывает данные на диск.Чтобы проверить это, я использую Unsafe.getByte(0), который вызывает сбой приложения с ошибкой SEG сразу после внесения изменений (как в следующей инструкции машинного кода), и все еще записывает изменения на диск.

Это не будет работатьесли ты тянешь власть, но ты должен быть очень быстрым.Вы можете использовать файлы, отображенные в памяти, для принудительного переноса данных на диск, прежде чем продолжить, но я не знаю, как вы можете проверить, действительно ли это работает.;)


У меня есть библиотека, которая может упростить использование файлов с отображением в памяти

https://github.com/peter-lawrey/Java-Chronicle

Это не долго для чтения, и вы можете использовать его какпример.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...