Java에서 전역적으로 고유한 식별자 생성
-
08-07-2019 - |
문제
요약: 저는 영구 Java 웹 애플리케이션을 개발 중이며, 중복을 방지하기 위해 지속하는 모든 리소스에 전역적으로 고유한 식별자가 있는지 확인해야 합니다.
작은 글씨:
- 저는 RDBMS를 사용하지 않기 때문에 Oracle에서 제공하는 것과 같은 멋진 시퀀스 생성기가 없습니다.
- 나는 그것이 빠르기를 원하며, 바람직하게는 모두 메모리에 저장되어 있기를 원합니다. 파일을 열고 일부 값을 증가시킬 필요가 없습니다.
- 스레드로부터 안전해야 합니다(한 번에 하나의 JVM만 ID를 생성해야 할 것으로 예상합니다).
- JVM 인스턴스화 전반에 걸쳐 일관성이 있어야 합니다.서버가 종료되었다가 시작되면 ID 생성기는 이전 인스턴스화에서 생성한 것과 동일한 ID를 다시 생성해서는 안 됩니다(또는 적어도 그 기회는 정말, 정말 희박해야 합니다. 수백만 개의 사전 설정된 리소스가 예상됩니다)
- EJB 고유 ID 패턴 기사에서 예제를 보았습니다.그것들은 나에게 적합하지 않습니다. (우리는 밀리초당 여러 리소스를 유지할 것이기 때문에 System.currentTimeMillis()에만 의존하고 싶지 않습니다.)
- 나는 제안된 답변을 살펴보았습니다. 이 질문.제가 우려하는 점은 시간이 지남에 따라 중복 ID를 받을 가능성이 얼마나 되는지입니다.사용 제안에 흥미가 있습니다. java.util.UUID 한 동안 UUID, 그러나 다시 한 번 말씀드리지만, 복제 가능성은 무한히 작아야 합니다.
- JDK6을 사용하고 있습니다.
해결책
UUID가 "충분히 좋다"고 확신합니다.사용 가능한 UUID는 340,282,366,920,938,463,463,374,607,431,770,000,000개입니다.
http://www.wilybeagle.com/guid_store/guid_explain.htm
"이 숫자를 관점에서 보면, 연간 운석에 부딪힐 위험은 170억분의 1의 확률로 추산됩니다. 즉, 확률은 약 0.00000000006(6 × 10−11)이며, 이는 운석이 몇 개 생성될 확률과 동일합니다. 1년에 수십조 개의 UUID가 있고 하나의 중복이 있습니다.즉, 향후 100년 동안 매초 10억 개의 UUID를 생성한 후에야 복제본이 하나만 생성될 확률은 약 50%가 됩니다.지구상의 모든 사람이 6억 개의 UUID를 소유하고 있다면 하나의 중복 확률은 약 50%입니다."
다른 팁
public class UniqueID {
private static long startTime = System.currentTimeMillis();
private static long id;
public static synchronized String getUniqueID() {
return "id." + startTime + "." + id++;
}
}
PC 당 고유 해야하는 경우 : 아마도 사용할 수 있습니다. (System.currentTimeMillis() << 4) | (staticCounter++ & 15)
또는 그런 것.
이를 통해 MS 당 16을 생성 할 수 있습니다. 더 필요한 경우 5로 전환하고 31로 ...
여러 PC에서 고유 해야하는 경우 기본 네트워크 카드의 MAC 주소를 결합해야합니다.
편집 : 명확히합니다
private static int staticCounter=0;
private final int nBits=4;
public long getUnique() {
return (currentTimeMillis() << nBits) | (staticCounter++ & 2^nBits-1);
}
NBITS를 MS 당 생성 해야하는 가장 큰 숫자의 제곱근으로 변경하십시오.
결국 롤오버됩니다. 아마도 20 년 또는 4시에 NBITS가있는 것.
메모리에서 RMI 원격 패키지에는 UUID 생성기가 포함되어 있습니다. 나는 그것이 조사 할 가치가 있는지 모르겠다.
내가 그것들을 생성해야 할 때 나는 일반적으로 현재 날짜 시간, 사용자 이름 및 컴퓨터의 IP 주소를 사용합니다. 기본적으로 아이디어는 컴퓨터/사람에 대해 알아낼 수있는 모든 것을 취한 다음이 정보의 MD5 해시를 생성하는 것입니다.
그것은 정말로 잘 작동하고 엄청나게 빠릅니다 (처음으로 MessageDigest를 초기화 한 후).
왜 이것을 좋아하지 않습니까?
String id = Long.toString(System.currentTimeMillis()) +
(new Random()).nextInt(1000) +
(new Random()).nextInt(1000);
Java UUID가 더 짧고 빠른 구현을 사용하려면 다음을 살펴보십시오.
Javadoc의 구현 선택 및 제한 사항을 참조하십시오.
다음은 사용 방법에 대한 단위 테스트입니다.