脉金捷脉金捷
主页
  • VuePress
  • VuePress2
  • Markdown基础命令
  • Java特性
  • Java修饰符
  • Java常见问题
  • Java LocalDate
  • Java Cloud ID
  • Docker-CentOS8
  • Docker-Nginx
  • Docker-Redis
  • Docker-MySQL
  • Docker-Nacos
  • Docker-Seata
  • Docker-Nodejs
  • Docker-runlike
  • Docker基础命令
  • Linux基础软件
  • Linux-SSH登录
  • Linux防火墙-iptables
  • Linux系统目录
主页
  • VuePress
  • VuePress2
  • Markdown基础命令
  • Java特性
  • Java修饰符
  • Java常见问题
  • Java LocalDate
  • Java Cloud ID
  • Docker-CentOS8
  • Docker-Nginx
  • Docker-Redis
  • Docker-MySQL
  • Docker-Nacos
  • Docker-Seata
  • Docker-Nodejs
  • Docker-runlike
  • Docker基础命令
  • Linux基础软件
  • Linux-SSH登录
  • Linux防火墙-iptables
  • Linux系统目录
  • Java特性
  • Java修饰符
  • Java常见问题
  • Java LocalDate
  • Java Cloud ID

微服务 id 生成策略

数据库自增 ID

最简单的实现方式是使用数据库的 id 自增策略,如 MySQL 的 auto_increment。如果两台数据库分别设置不同步长,可以生成不重复 ID,从而实现高可用。

  • 优点
    • 实现简单,容易理解,单调自增,绝对有序。
  • 缺点
    • 强依赖 DB,当 DB 异常时整个系统不可用,属于致命问题。ID 发号性能瓶颈限制在单台 MySQL 的读写性能。

UUID 系列

参考:https://zhuanlan.zhihu.com/p/70375430

结合机器的网卡、当地时间、一个随记数来生成 UUID。存在一些 UUID 的变种也是不错的实现。

  • 优点

    • 本地生成,生成简单,性能非常好,高可用。
  • 缺点

    • 长度过长,不易存储,无序不可读,查询效率低。
    • 信息不安全,基于 MAC 地址生成 UUID 的算法可能会造成 MAC 地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。
    • UUID 的无序性可能会引起数据位置频繁变动,严重影响性能。

Redis 实现 ID

Redis 的所有命令操作都是单线程的,本身提供像 incr 和 increby 这样的自增原子命令,所以能保证生成的 ID 肯定是唯一有序的。 举例,使用 Redis 来生成每天从 0 开始的流水号。比如订单号 = 日期 + 当日自增长号。可以每天在 Redis 中生成一个 Key ,使用 INCR 进行累加。

参考:https://www.cnblogs.com/agilestyle/p/13194027.html

  • 优点
    • 灵活方便,且性能优于数据库。
    • 数字 ID 天然排序,通过合理设计可以得到更具有表达能力的 ID。
  • 缺点
    • 引入 Redis,编码和配置的工作量比较大。
    • 如果 ID 是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定 URL 即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要 ID 无规则、不规则。

Twitter 的 snowflake 算法生成 ID

GitHub:https://github.com/twitter-archive/snowflake/releases/tag/snowflake-2010

参考:https://www.cnblogs.com/xiaofeiyang/p/13111548.html

  • 优点

    • 时间有序,毫秒数在高位,自增序列在低位,整个 ID 都是趋势递增的。
    • 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成 ID 的性能也是非常高的。
    • 可以根据自身业务特性分配 bit 位,非常灵活。
    • Long 型。
  • 缺点

    • 依赖于机器的时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。

百度 UidGenerator

参考:https://www.cnblogs.com/yeyang/p/10226284.html

GitHub:https://github.com/baidu/uid-generator

  • 优点
    • 同上 Twitter 的 snowflake 算法生成 ID
  • 缺点
    • 需要 MySQL(内置 WorkerID 分配器, 启动阶段通过 DB 进行分配; 如自定义实现, 则 DB 非必选依赖)

美团 Leaf

参考:https://tech.meituan.com/2019/03/07/open-source-project-leaf.html

GitHub:https://github.com/Meituan-Dianping/Leaf

  • 优点

    • 高可用容灾。
    • ID 号码是趋势递增的 8byte 的 64 位数字,满足数据库存储的主键要求。
  • 缺点

    • DB 宕机会造成整个系统不可用。
    • 比较复杂。

MongoDB 的 ObjectId

参考:https://docs.mongodb.com/manual/reference/method/ObjectId/

通过“时间+机器码+pid+inc”共 12 个字节,通过 4+3+2+3 的方式最终标识成一个 24 长度的十六进制字符。

  • 优点
    • 轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它。
    • 本地生成,含时间戳,有序,成本低。
    • 安全性高。
    • 比较短,24 位
  • 缺点
    • 比较长,难于记忆。
    • 使用机器 ID 和进程 ID,64 位 Long 无法存储,只能生成特殊 ObjectId 对象。
Last Updated: 2/25/22, 3:38 PM
Contributors: maijinjie