Создайте уникальный ID в Java, чтобы пометить группы связанных записей в журнале

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

использование новой даты () в качестве уникального идентификатора

создание глобального уникального идентификатора в Java

Я пытаюсь реализовать функцию, где мы можем выявить определенные события в файл журнала. Эти события должны быть связаны с уникальным идентификатором. Я пытаюсь придумать со стратегией для этого уникального поколения ID. Идентификатор должен иметь 2 части : некоторые статические данные + некоторые динамические информацию Журналы можно искать шаблон, когда требуется отладка событий. У меня есть три способа:--1-->

  • статическая информация + время даты Joda ("abc" + 2014-01-30T12:36: 12.703)
  • статическая информация + атомное целое число
  • статическая информация + UUID

для области этого вопроса несколько JVMs не рассматриваются. Я необходимо эффективно генерировать уникальные идентификаторы на одном JVM. Кроме того, я не смогу использовать решение, зависящее от базы данных.

какая из 3 вышеупомянутых стратегий работает лучше всего ?

  • если не один из вышеперечисленных, любая другая стратегия ?
  • время Джода надежная стратегия ? JVM является одиночным, но будут одновременные пользователи, поэтому могут быть одновременные события.
  • в сочетании с одной из вышеперечисленных / других стратегий, я нужно сделать мой метод потокобезопасным / синхронизированным ?

3 ответов


У меня была такая же потребность, как и у вас, различая поток связанных записей, чередующихся с другими несвязанными записями в журнале. Я испробовал все три предложенных вами подхода. Мой опыт был в 4D не Java, но похожие.

Времени

в моем случае я использовал значение даты-времени, разрешенное на целые секунды. Это просто слишком большая степень детализации. У меня легко были столкновения, когда несколько событий начинались в течение одной секунды. Чертовы быстрые компьютеры!

в вашем случае с любой из связанных java.утиль.Дата или Joda Времени (настоятельно рекомендуется для других целей), как решимость миллисекунд. Миллисекунда-это долгое время в современных компьютерах, поэтому я не рекомендую это.

в Java 8, новый java.время.* пакет (вдохновленный Joda-Time, определенный JSR 310) устранить в наносекундах. Это может показаться лучшим идентификатором, но нет. Для один вещь, ваш физические часы компьютера могут не поддерживать такое прекрасное разрешение. Во-вторых, компьютеры становятся все быстрее. Наконец, часы компьютера могут быть сброшены, действительно это is сброс часто, как компьютерные часы дрейфа совсем немного. Современные ОС сбрасывают свои часы, часто проверяя с помощью сервер времени либо локально, либо через Интернет.

кроме того, журналы уже имеют метку времени, поэтому мы не получаем никакой дополнительной выгоды, используя дату-время в качестве нашего идентификатор. Действительно, наличие второй даты-времени в записи журнала может фактически вызвать путаницу.

Серийный Номер

на "атомное число", я предполагаю, что вы имеете в виду серийный номер, увеличивающийся с ростом числа.

Это кажется излишним для ваших целей.

  • вас не волнует последовательность, она не имеет смысла для этой цели группировки записей журнала. Вам на самом деле все равно, пришла ли одна группа N-го числа до или после другой группы.
  • поддержание последовательности-это боль, точка потенциального отказа. Я всегда в конечном итоге сталкивался с административными проблемами с поддержанием последовательности.

таким образом, этот подход добавляет риск, не добавляя никакой особой выгоды.

UUID

Бинго! Как раз то, что тебе нужно.

на UUID легко генерируется, используя либо в комплекте java.утиль.Способность класса UUID генерировать UUID версии 3 или 4 или использовать сторонние библиотека или доступ к командной строке .

для очень большого объема, [Версия 1] UUID (MAC + дата-время + случайное число) будет лучше. Для ведения журнала Вариант 4 UUID (полностью случайный) абсолютно приемлемо.

столкновение не является реалистичной проблемой. Особенно для ограниченного числа значений, которые вы будете генерировать для журналов. Меня поражают люди, которые, не понимая цифр, говорят, что никогда бы не поняли. замените последовательность UUID. Тем не менее, при нажатии каждый программист и системный администратор, которого я знаю, испытывал сбои по крайней мере с одной последовательностью.

отсутствие забот о поток-безопасности. Нет проблем с конфликтом (см. мои результаты теста на еще один мой ответ).

Другим преимуществом UUID является то, что его обычный шестнадцатеричное представление, например:

6536ca53-bcad-4552-977f-16945fee13e2

...легко узнаваем. При распознавании читатель сразу же узнает, что строка должна быть уникальным идентификатором. Таким образом, это присутствие в вашем журнале само документируется.

Я нашел UUIDs быть Скотч вычислительной техники. Я продолжаю находить им новое применение.

Итак, в начале рассматриваемого кода создайте UUID, а затем вставьте его в каждую из связанных записей журнала.

хотя шестнадцатеричное строковое представление UUID трудно читать и писать, на практике вам нужно сканировать только несколько цифр в начале или конце. Или используйте copy-paste с функциями поиска и фильтрации в наших современных консольных инструментах.

несколько фактов

  • UUID известен в мире Microsoft как GUID.
  • UUID является не строка, но 128-битное значение. Биты, просто биты в памяти, "вкл." / " выкл." ценности. Некоторые базы данных, такие как Postgres, знать, как обрабатывать и хранить UUID как такие 128-битные значения. Если мы хотим показать эти биты людям, мы могли бы использовать серию из 128 цифр "1" и "0". Но люди не очень хорошо пытаются читать или писать 128 цифр единиц и нулей. Поэтому мы используем шестнадцатеричное представление. Но даже 32 шестнадцатеричных цифры слишком много для людей, поэтому мы разбиваем строку на группы, разделенные дефисами, как показано выше, в общей сложности 36 письмена.
  • спецификация для UUID совершенно ясно, что шестнадцатеричное представление должно быть строчные. Спецификация говорит, что при создании UUID из строкового ввода верхний регистр должен допускаться. Но при создании шестнадцатеричной строки она должна быть строчной. Многие реализации UUIDs игнорируют это требование. Я предлагаю придерживаться спецификации и конвертировать ваши шестнадцатеричные строки UUID в нижний регистр.

MDC – Сопоставленная Диагностика Контекст

Я еще не использовал MDC, но хочу указать на это...

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

быстрая вводная статья Log4j MDC (сопоставленный диагностический контекст): что и почему .

лучшее ведение журнала фасад, SLF4J, предлагает такие функция MDC. Лучшая реализация этого фасада,Logback, имеет глава документирование его функции MDC.


компьютеры быстры, используя время для попытка для создания уникального значения произойдет сбой.

вместо этого используйте UUID. От JSE 6.0 UUID API страница "[UUID] класс, представляющий неизменяемый универсальный уникальный идентификатор (UUID)."

вот код:

import java.util.UUID;

private String id;

id = UUID.randomUUID().toString();

Я написал простую службу, которая может генерировать полу-уникальные непоследовательные 64-битные длинные числа. Его можно раскрыть на множественных машинах для дублирования и масштабируемости. Он использует ZeroMQ для обмена сообщениями. Для получения дополнительной информации о том, как это работает, посмотрите на GitHub странице: zUID