设计一个订单号生成系统,主要考虑到生成的订单号需要满足的几个要求:唯一性、可扩展性、以及可能的业务相关性。以下是几种常见的解决方案及相应的示例代码:
目录
单号的生成器的几种实现方式:
UUID
最简单的方法是使用UUID生成唯一的订单号。UUID(Universally Unique Identifier)是一种广泛使用的标识符,由128位组成,通常以32个十六进制数字表示,分为五组,形式为8-4-4-4-12的字符串,例如123e4567-e89b-12d3-a456-426614174000。
UUID全球唯一,实现简单,但缺点是UUID较长,没有任何实质含义不易记忆和存储。
public static String generateUUID() {
// 生成一个UUID
UUID uuid = UUID.randomUUID();
// 将UUID转换为字符串
String uuidAsString = uuid.toString();
// 返回UUID字符串
return uuidAsString;
}
时间+随机数/序列
public class OrderNumberGenerator {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
private static final int RANDOM_NUM_BOUND = 10000; // 定义随机数范围
public static String generateOrderNumber(String prefix) {
// 生成时间戳部分
String timestamp = dateFormat.format(new Date());
// 生成随机数部分
int randomNumber = ThreadLocalRandom.current().nextInt(RANDOM_NUM_BOUND);
// 组合成订单号
return prefix + timestamp + String.format("%04d", randomNumber);
}
}
Snowflake ID结构
一个 Snowflake ID 通常是一个 64 位的整数,其结构如下:
Timestamp (41 bits) | Node ID (10 bits) | Sequence (12 bits) |
-
Timestamp(时间戳) - 41 位
-
表示自某个固定时间点(通常是一个纪元,例如 1970 年 1 月 1 日)以来的毫秒数。
-
可以支持大约 69 年的时间跨度(2^41 毫秒)。
-
-
Node ID(节点 ID) - 10 位
-
用于标识生成 ID 的机器(或节点)。如果系统有多个节点,每个节点都会有一个唯一的 ID。
-
可以支持最多 1024 个不同的节点(2^10)。
-
-
Sequence(序列号) - 12 位
-
在同一毫秒内生成的 ID 的序列号。每个节点在同一毫秒内可以生成最多 4096 个 ID(2^12)。
-
序列号每次生成时会递增。
-