2008-10-10 2 views
11

Резюме: Я разрабатываю постоянное веб-приложение Java, и мне нужно убедиться, что все оставшиеся ресурсы имеют глобально уникальные идентификаторы для предотвращения дублирования.Создание глобально уникального идентификатора в Java

Штраф печати:

  1. Я не использую РСУБД, поэтому у меня нет каких-либо фантазии генераторы последовательности (например, как один, предоставленной Oracle)
  2. я хотел он должен быть быстрым, желательно все в памяти - мне бы не пришлось открывать файл и увеличивать некоторое значение
  3. Он должен быть потокобезопасным (я ожидаю, что только один JVM за один раз должен будет генерировать ID)
  4. Должна быть согласованность между мгновенными JVM. Если сервер выключится и запустится, генератор ID не должен генерировать те же идентификаторы, которые он сгенерировал в предыдущих экземплярах (или, по крайней мере, шанс должен быть действительно, очень тонким - я ожидаю много миллионов ресурсов)
  5. Я видел примеры в уникальной статье шаблона EJB. Они не будут работать для меня (я бы предпочел не полагаться исключительно на System.currentTimeMillis(), потому что мы будем хранить несколько ресурсов за миллисекунду).
  6. Я рассмотрел ответы, предложенные в this question. Моя забота о них такова, какова вероятность того, что я получу дубликат ID с течением времени? Меня заинтриговало предложение использовать java.util.UUID для UUID, но опять же, вероятность дублирования должна быть бесконечно малой.
  7. Я использую JDK6
+0

Вы используете несколько экземпляров приложения на разных машинах? Если да, можете ли вы запускать машины партиями - так что, вероятно, начнется несколько процессов в той же миллисекунде? Если злоумышленник находит способ вызвать конфликт UUID, это может поставить под угрозу безопасность вашего приложения? – 2012-03-17 16:09:09

+0

(A) Какой объем идентификаторов будет сгенерирован? Как быстро? (Сколько раз в секунду/минуту) (B) Да, UUID были изобретены именно для вашей цели. – 2014-02-03 23:19:48

ответ

30

Довольно уверен UUID, являются «достаточно хорошо». Имеются 340,282,366,920,938,463,463,374,607,431,770,000,000 UUIDs.

http://www.wilybeagle.com/guid_store/guid_explain.htm

«Для того, чтобы поместить эти цифры в перспективе, свой ежегодный риск попадания метеорита оценивается в один шанс в 17 миллиардов, это означает, что вероятность составляет около +0,00000000006 (6 × 10-11) , что эквивалентно шансам создания нескольких десятков триллионов UUID за год и наличия одного дубликата. Другими словами, только после генерации 1 миллиарда UUID каждую секунду в течение следующих 100 лет вероятность создания только одного дубликата будет примерно равна 50%. Вероятность одного дубликата будет составлять около 50%, если каждый человек на земле владеет 600 млн. UUID «

http://en.wikipedia.org/wiki/Universally_Unique_Identifier

+0

Хорошая ссылка! Поэтому можно сделать вывод, что если я использую UUID.randomUUID() в моем приложении, вероятность его генерации одного и того же UUID дважды бесконечно мала, а затем ...? – Julie 2008-10-10 20:34:58

+0

Да, бесконечно – 2008-10-10 20:36:46

+1

Ну, просто потому, что существует так много возможных значений, это не обязательно означает, что они достаточно хорошо написали алгоритм, чтобы получить хорошее случайное распределение. Опять же, дизайнеры класса UUID, вероятно, задумались над ним, чем я мог бы днем! – Julie 2008-10-10 20:38:44

1

Если это необходимо для каждого компьютера, вы можете использовать (System.currentTimeMillis() << 4) | (staticCounter++ & 15) или что-то в этом роде.

Это позволит вам генерировать 16 в мс. Если вам нужно больше, сдвиньте на 5, и это будет 31 ...

Если это необходимо для уникального использования на нескольких ПК, вы также должны объединить MAC-адрес вашей основной сетевой карты.

редактировать: уточнить

private static int staticCounter=0; 
private final int nBits=4; 
public long getUnique() { 
    return (currentTimeMillis() << nBits) | (staticCounter++ & 2^nBits-1); 
} 

и изменить Nbits корню квадратному из наибольшего числа вы должны должны генерировать в мс.

В конечном итоге он перевернется.Вероятно, 20 лет или что-то с nBits на 4.

0

Из памяти удаленные пакеты RMI содержат генератор UUID. Я не знаю, стоит ли смотреть на это.

Когда мне приходилось их генерировать, я обычно использую хешсум MD5 текущего времени, имя пользователя и IP-адрес компьютера. В основном идея состоит в том, чтобы взять все, что вы можете узнать о компьютере/человеке, а затем генерировать хеш MD5 этой информации.

Он работает очень хорошо и невероятно быстро (как только вы впервые инициализировали MessageDigest).

1
public class UniqueID { 
    private static long startTime = System.currentTimeMillis(); 
    private static long id; 

    public static synchronized String getUniqueID() { 
     return "id." + startTime + "." + id++; 
    } 
} 
0

почему бы не сделать так

String id = Long.toString(System.currentTimeMillis()) + 
    (new Random()).nextInt(1000) + 
    (new Random()).nextInt(1000); 
0

, если вы хотите использовать более короткие и быстрые реализации, что Java UUID взглянуть на:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/main/java/org/spf4j/concurrent/UIDGenerator.java

посмотреть варианты реализации и ограничения в javadoc.

здесь юнит тест о том, как использовать:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/test/java/org/spf4j/concurrent/UIDGeneratorTest.java

Смежные вопросы