searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Java中常用的分布式ID生成方式UUID源码分析

2024-04-30 05:51:46
13
0

介绍

在当今的互联网公司中,业务多是分布式部署的,生成一个分布式业务中的唯一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的主要逻辑为:

  1. 首先通过SecureRandom生成随机字节数组,
     
  2. 设置字节数组的特定位,生成的UUID。   

      3. 字节数组转换为UUID对象。

 

应用场景

  1. 在分布式系统中,UUID可用于生成唯一ID,例如生成订单号,避免数据冲突。
  2. 在数据库中,UUID可作为主键,避免数据冲突。
  3. 在日志中,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);
    }
}

 

0条评论
0 / 1000
luguorui
2文章数
0粉丝数
luguorui
2 文章 | 0 粉丝
luguorui
2文章数
0粉丝数
luguorui
2 文章 | 0 粉丝
原创

Java中常用的分布式ID生成方式UUID源码分析

2024-04-30 05:51:46
13
0

介绍

在当今的互联网公司中,业务多是分布式部署的,生成一个分布式业务中的唯一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的主要逻辑为:

  1. 首先通过SecureRandom生成随机字节数组,
     
  2. 设置字节数组的特定位,生成的UUID。   

      3. 字节数组转换为UUID对象。

 

应用场景

  1. 在分布式系统中,UUID可用于生成唯一ID,例如生成订单号,避免数据冲突。
  2. 在数据库中,UUID可作为主键,避免数据冲突。
  3. 在日志中,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);
    }
}

 

文章来自个人专栏
分布式1
2 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
1
1