news 2026/8/30 10:18:47

雪花算法ID重复了?惨痛教训:请勿轻易造轮子!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
雪花算法ID重复了?惨痛教训:请勿轻易造轮子!

来源:juejin.cn/post/7507203999102648360

👉 欢迎加入小哈的星球,你将获得:专属的项目实战(多个项目) / 1v1 提问 /Java 学习路线 /学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《Spring AI 项目实战》正在更新中..., 基于 Spring AI + Spring Boot 3.x + JDK 21;

  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍;演示地址:http://116.62.199.48:7070/

  • 《从零手撸:前后端分离博客项目(全栈开发)》2期已完结,演示链接:http://116.62.199.48/;

  • 专栏阅读地址:https://www.quanxiaoha.com/column

截止目前,累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中..后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有4100+小伙伴加入

最近我们线上系统发生了一起严重事故:订单号/流水号出现了重复,影响了核心业务流程。最终定位到根源:一个自研的二方包雪花算法ID生成器出现了问题。

下面我们来回顾一下雪花算法的标准结构,分析问题出在哪,并总结一些通用的设计建议。

一、标准雪花算法(Snowflake)

标准的Snowflake ID由一个64位long型整数构成:

+----------------------------------------------------------------------------------------------------+ | 1 Bit | 41 Bits 时间戳 | 5 Bits 数据中心ID | 5 Bits 机器ID | 12 Bits 序列号 | +----------------------------------------------------------------------------------------------------+
  • 1位符号位:始终为0,确保生成正数。

  • 41位时间戳:记录与固定起始时间的毫秒差,可支持约69年。

  • 10位机器ID:用于标识不同节点。

  • 12位序列号:在同一毫秒内生成多个ID时使用,最多支持每毫秒生成4096个ID。

优点:

  • 高性能生成唯一ID,按时间有序,适用于分布式环境。

二、我们的“定制版”雪花算法:问题在哪?

我们使用的二方包雪花算法结构如下(根据排查推测):

+----------------------------------------------------------------------------------------------------+ | 31 Bits 时间戳Delta | 13 Bits 数据中心ID | 4 Bits 工作ID | 8 Bits 业务ID | 8 Bits 序列号 | +----------------------------------------------------------------------------------------------------+

看起来字段丰富,但存在严重问题:

1. 时间戳仅保留31位,最多支持24.85天!
  • 左移33位后只用31位时间戳,

  • 超过 2^31 毫秒后开始循环,

  • 我们自定义的起始时间是2018年,2025年时早已绕了无数圈。

2. BusinessId 用的是 IP 最后一段

使用的IPy用点分隔的最后一位,即192.168.0.1的1,极容易重复。

3. WorkId 和 DataCenterId 未配置,全为0

相当于所有实例共享同一节点标识,唯一性形同虚设。

最终结果:时间轮回 + IP冲突 + 序列重复,ID彻底撞车。

三、教训总结

通用组件不建议自研

雪花算法涉及时钟回拨、位运算、分布式协调等关键细节,成熟组件更稳妥。

不盲信二方包

无论谁写的代码,都要看清实现逻辑,理解其唯一性保障机制。

合理设置机器ID

靠IP后缀太脆弱,建议集中规划,统一分配Worker ID和DataCenter ID。

提前覆盖边界场景

模拟长时间运行、序列号溢出、时间回拨等极端情况,确保系统稳健。

四、推荐做法

使用成熟的开源实现,如 Hutool、Baomidou 等:

// Hutool 示例 Snowflake snowflake = IdUtil.getSnowflake(1, 1); long id = snowflake.nextId(); // Baomidou 示例(支持从 IP/MAC 自动推导,也可手动指定) DefaultIdentifierGenerator generator = new DefaultIdentifierGenerator(1, 1); // workerId=1, dataCenterId=1 long id = generator.nextId("user");

对于中大型系统,DataCenterId 一般用来标识不同的机房或者 AZ (Availability Zone)。

WorkerId 的配置策略可以根据系统规模逐步演进:

  • 简单方式:通过配置文件手动指定。这种方式配置简便,适用于开发环境或单机部署。

  • 标准方式:将 IP 与端口号(或进程号)拼接后进行哈希,再对 WorkerId 总数取模。具备一定自动化能力,不依赖外部系统,适用于中小规模部署。

  • 中级方案:依赖注册中心(如 Eureka、Nacos),在服务注册时分配编号,结合服务ID保障唯一性。

  • 高级方案:使用 Redis、Zookeeper 等集中协调 WorkerId 分配与释放,支持动态扩容、避免冲突。

随着系统规模扩大,推荐逐步引入更复杂但更稳妥的机制,避免一开始就过度设计。

五、其它建议:不要将业务标志拼入ID中

有时我们为了确保唯一性,会试图将业务信息(如类型前缀、模块编号)拼接进ID。但这种做法会带来一系列问题:

  • 会导致 ID 非全数字,失去原本按时间递增的排序特性,影响数据库索引效率;

  • ID长度变得不规则或偏长,可能增加存储成本,也会影响日志展示、用户体验;

  • 若业务字段含义变动,还可能造成数据兼容性问题。

更稳妥的做法是将业务字段单独存储,ID仅用于唯一标识和排序。

六、结语

别为造轮子而造轮子,尤其在通用组件上,不可抱侥幸心理。

👉 欢迎加入小哈的星球,你将获得:专属的项目实战(多个项目) / 1v1 提问 /Java 学习路线 /学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《Spring AI 项目实战》正在更新中..., 基于 Spring AI + Spring Boot 3.x + JDK 21;

  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍;演示地址:http://116.62.199.48:7070/

  • 《从零手撸:前后端分离博客项目(全栈开发)》2期已完结,演示链接:http://116.62.199.48/;

  • 专栏阅读地址:https://www.quanxiaoha.com/column

截止目前,累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中..后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有4100+小伙伴加入

1. 我的私密学习小圈子,从0到1手撸企业实战项目~ 2. Spring Task定时任务:3行代码解放双手,告别重复劳动! 3. JDK25都出来了,但为什么很多公司还在坚持用JDK8? 4. 面试官:Git 如何撤回已 Push 的代码?问倒一大片。。。
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。 获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。
PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。 点“在看”支持小哈呀,谢谢啦
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 15:16:45

CloudStream媒体文件管理终极指南:从混乱到有序的完整解决方案

CloudStream媒体文件管理终极指南:从混乱到有序的完整解决方案 【免费下载链接】cloudstream Android app for streaming and downloading media. 项目地址: https://gitcode.com/GitHub_Trending/cl/cloudstream 你是否曾因手机存储空间被大量媒体文件占据而…

作者头像 李华
网站建设 2026/8/30 3:34:39

时序数据可视化终极指南:AI工具让数据分析如此简单

还在为复杂的时间序列数据发愁吗?面对密密麻麻的时间戳和数值,想要快速生成专业图表却不知从何下手?别担心,这款AI驱动的数据可视化工具将彻底改变你的数据分析体验! 【免费下载链接】data-formulator 🪄 C…

作者头像 李华
网站建设 2026/8/29 13:17:29

智能体协作框架设计:多个Anything-LLM实例分工合作

智能体协作框架设计:多个Anything-LLM实例分工合作 在企业知识系统日益复杂的今天,一个“万能助手”式的单一AI模型正逐渐显露出疲态。面对海量文档更新、多部门权限隔离和高并发访问需求,传统的单体架构常常陷入响应延迟、数据混杂与维护困难…

作者头像 李华
网站建设 2026/8/29 3:53:05

Gin 真的是“真菌”吗?—— 一篇引发热议的“反 Gin”檄文解读

大家好,我是Tony Bai。“Gin 就像是一种伪装成软件库的阴险真菌:它很容易感染,一旦沾上就几乎无法去除,除非你极其小心,否则还会传染给你的朋友。”2025 年 12 月,Efron Licht 发布了一篇名为《Gin 是一个非…

作者头像 李华
网站建设 2026/8/30 4:14:36

在海康工作是怎么样的?

周末跟一粉丝聊天,聊到了在海康的工作情况下面以第一人称描述我既待过杭州总部做嵌入式开发,也在分公司做过技术支持,身边不少朋友问我这边的真实情况,今天就聊聊,给大家个参考 —— 要是真考虑来,有些事得…

作者头像 李华
网站建设 2026/8/30 12:11:32

2025年12月语言榜单揭秘:Python 确实强得离谱!

大家好,我是菜哥!12月的TIOBE编程语言排行榜不知道大家看到没有,Python又是第一名,23.37%的市场份额,这已经是它连续霸榜的第N个月了。但真正让我惊讶的,是C语言居然杀回了第二名的位置。说实话&#xff0c…

作者头像 李华