介绍
在当今的互联网公司中,业务多是分布式部署的,生成一个分布式业务中的唯一ID对于业务来说至关重要。
在Java中,UUID是用来生成唯一ID一种工具,有助于确保数据在分布式系统中的唯一性。
本文通过简要分析UUID的源码,帮助读者理解其工作原理和生成唯一ID的主要逻辑。文末给出如何在分布式系统中使用UUID。
UUID源码分析
下面列出Java中UUID的核心代码:
public final class UUID implements java.io.Serializable, Comparable<UUID> {
/**
* Explicit serialVersionUID for interoperability.
*/
private static final long serialVersionUID = -4856846361193249489L;
/*
* The most significant 64 bits of this UUID.
*
* @serial
*/
private final long mostSigBits;
/*
* The least significant 64 bits of this UUID.
*
* @serial
*/
private final long leastSigBits;
/*
* The random number generator used by this class to create random
* based UUIDs. In a holder class to defer initialization until needed.
*/
private static class Holder {
static final SecureRandom numberGenerator = new SecureRandom();
}
// Constructors and Factories
/*
* Private constructor which uses a byte array to construct the new UUID.
*/
private UUID(byte[] data) {
long msb = 0;
long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length";
for (int i=0; i<8; i++)
msb = (msb << 8) | (data[i] & 0xff);
for (int i=8; i<16; i++)
lsb = (lsb << 8) | (data[i] & 0xff);
this.mostSigBits = msb;
this.leastSigBits = lsb;
}
/**
* Constructs a new {@code UUID} using the specified data. {@code
* mostSigBits} is used for the most significant 64 bits of the {@code
* UUID} and {@code leastSigBits} becomes the least significant 64 bits of
* the {@code UUID}.
*
* @param mostSigBits
* The most significant bits of the {@code UUID}
*
* @param leastSigBits
* The least significant bits of the {@code UUID}
*/
public UUID(long mostSigBits, long leastSigBits) {
this.mostSigBits = mostSigBits;
this.leastSigBits = leastSigBits;
}
/**
* Static factory to retrieve a type 4 (pseudo randomly generated) UUID.
*
* The {@code UUID} is generated using a cryptographically strong pseudo
* random number generator.
*
* @return A randomly generated {@code UUID}
*/
public static UUID randomUUID() {
SecureRandom ng = Holder.numberGenerator;
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new UUID(randomBytes);
}
// .....
}
从上述代码中可以看到,UUID生成唯一ID的主要逻辑为:
- 首先通过SecureRandom生成随机字节数组,
- 设置字节数组的特定位,生成的UUID。
3. 字节数组转换为UUID对象。
应用场景
- 在分布式系统中,UUID可用于生成唯一ID,例如生成订单号,避免数据冲突。
- 在数据库中,UUID可作为主键,避免数据冲突。
- 在日志中,UUID可用于traceId,用于追踪不同业务的日志。
如何使用
import java.util.UUID;
public class Main {
public static void main(String[] args) {
String randomUUID = UUID.randomUUID().toString();
System.out.println("uuid: " + randomUUID);
}
}