当前位置: 首页 > news >正文

Java 实现 MongoDB ObjectId 算法

以下是 Java 实现 MongoDB ObjectId 算法的完整代码,该实现严格遵循其 12字节 结构规范,包含时间戳、机器标识、进程ID和计数器四部分。


import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.NetworkInterface;
import java.security.SecureRandom;
import java.time.Instant;
import java.util.Enumeration;
import java.util.concurrent.atomic.AtomicInteger;public class MongoObjectId {private static final int COUNTER_MAX = 0xFFFFFF; // 3字节最大值private static final AtomicInteger counter = new AtomicInteger(new SecureRandom().nextInt());private static final byte[] machineId = createMachineId();private static final byte[] processId = createProcessId();// 生成12字节ObjectIdpublic static byte[] generate() {byte[] objectId = new byte[12];// 4字节时间戳(秒级)int timestamp = (int) Instant.now().getEpochSecond();objectId[0] = (byte) (timestamp >> 24);objectId[1] = (byte) (timestamp >> 16);objectId[2] = (byte) (timestamp >> 8);objectId[3] = (byte) timestamp;// 3字节机器标识System.arraycopy(machineId, 0, objectId, 4, 3);// 2字节进程IDSystem.arraycopy(processId, 0, objectId, 7, 2);// 3字节计数器(线程安全)int cnt = counter.incrementAndGet() & COUNTER_MAX;objectId[9] = (byte) (cnt >> 16);objectId[10] = (byte) (cnt >> 8);objectId[11] = (byte) cnt;return objectId;}// 生成16进制字符串表示public static String toHexString(byte[] bytes) {StringBuilder sb = new StringBuilder();for (byte b : bytes) {sb.append(String.format("%02x", b));}return sb.toString();}// 获取3字节机器标识(MAC地址哈希)private static byte[] createMachineId() {try {Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();while (interfaces.hasMoreElements()) {NetworkInterface ni = interfaces.nextElement();if (!ni.isLoopback() && ni.getHardwareAddress() != null) {byte[] mac = ni.getHardwareAddress();return new byte[]{mac[0], mac[1], mac[2]};}}} catch (Exception e) {// 失败时使用随机数}return new byte[]{(byte) new SecureRandom().nextInt(),(byte) new SecureRandom().nextInt(),(byte) new SecureRandom().nextInt()};}// 获取2字节进程IDprivate static byte[] createProcessId() {RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();String processName = runtimeMxBean.getName();System.out.println("当前进程: " + processName);int pid = Integer.parseInt(processName.split("@")[0]);System.out.println("当前进程ID: " + pid);return new byte[]{(byte) (pid >> 8), (byte) pid};}public static void main(String[] args) {byte[] objectId = generate();System.out.println("生成的ObjectId: " + toHexString(objectId));objectId = generate();System.out.println("生成的ObjectId: " + toHexString(objectId));objectId = generate();System.out.println("生成的ObjectId: " + toHexString(objectId));}
}

实现特点:

1. 时间戳部分:采用Unix秒级时间戳,确保时间有序性
2. 机器标识:通过MAC地址哈希生成,保证分布式环境唯一性
3. 进程ID:通过ManagementFactoryRuntimeMXBean实现,这是最可靠且跨平台的方式
4. 原子计数器:确保单进程高并发下的唯一性
5. 最终输出符合MongoDB标准的24位十六进制格式

该实现严格遵循MongoDB ObjectId的规范:

  • 总长度:12字节
  • 组成结构:4字节时间戳 + 3字节机器标识 + 2字节进程ID + 3字节计数器
  • 唯一性保证:同一进程、同一秒内最多可生成16777216(2^24)个不重复ID

实际应用场景:

  • 分布式系统主键生成
  • 日志追踪标识
  • 需要时间排序的数据记录
  • 替代UUIDv4的更高性能方案
http://www.dtcms.com/a/352835.html

相关文章:

  • Python常见设计模式3: 行为型模式
  • 数据分析与数据挖掘
  • 【技术教程】如何为ONLYOFFICE协作空间开发文件过滤UI插件
  • string类的学习及模拟
  • vue拖动排序,vue使用 HTML5 的draggable拖放 API实现内容拖并排序,并更新数组数据
  • 【无标题】淘宝直播间详情数据
  • 云原生安全架构设计与零信任实践
  • 三格电子——高频一体式工业级RFID读写器的应用
  • 核心内涵解析:销采一体化 CRM 是什么?
  • 贴片式TE卡 +北京君正+Rk瑞芯微的应用
  • 亚马逊ASIN定投广告的智能化突破:从人工苦力到数据驱动的华丽转身
  • Part 1️⃣:相机几何与单视图几何-第六章:相机模型
  • Android中点击链接跳转到对应App页面的底层原理
  • Linux 云服务器日志清理自动化方法
  • 第二阶段Winfrom-8:特性和反射,加密和解密,单例模式
  • 点评项目(Redis中间件)第一部分Redis基础
  • golang 12 package 和 module
  • SegEarth-R1: Geospatial Pixel Reasoning via Large Language Model
  • week5-[字符数组]长度和
  • GraphRAG数据可视化
  • Java中JUnit知识点
  • Qt表格组件封装与远程数据库连接:从数据展示到交互体验
  • 阿里云——应用交付与负载均衡
  • 用户体验设计 | 从UX到AX:人工智能如何重构交互范式?
  • 阿里云轻量应用服务器与ECS对比
  • 4步用代码拆解数学建模中的TOPSIS评价决策! ! !
  • 树的常见算法及Java实现
  • LeetCode算法日记 - Day 23: 外观数列、数青蛙
  • 欧洲数字化养殖平台 Herdwatch 借力 Iceberg + StarRocks 提升分析能力
  • 【Matplotlib学习】驾驭画布:Matplotlib 布局方式从入门到精通完全指南