• 网易云课堂-分布式订单号生成策略


    订单号要求

    • 全局唯一
    • 长度固定
    • 趋势递增
    • 高并发
    • 高效率(整型、不能太长)

    策略一:UUID

    • 缺点:无序、效率低、字符串、过长(占用空间)、可读性差

    策略二:数据库自增

    • 自增参数设置
      show varivables like 'auto_inc';
      -- 起始
      set @@auto_increment_offset=2
      -- 步长
      set @@auto_increment_increment=5
      
    • 可通过设置不同数据库自增参数来并发获取订单号
    • 缺点
      • 不利于数据库服务器伸缩(步长限制)
      • 不利于数据迁移

    策略三:雪花算法

    • SnowFlake:最原始的版本来源于Twitter,是用Scala实现的。地址为 https://github.com/twitter-archive/snowflake。

    • SnowFlake:是一个64bit的整数分别由四部分组成: 1(最高位固定为0表示整数)+41(时间戳以毫秒为单位)+10(机器编号用来区分不同服务器)+12(序列号,同一毫秒同一机器可支持4095个序列号)。

    • 根据源码可知最后的结果是由时间戳,机器码,工作码,序列数位或运算(|)得到的结果。

      • 时间戳:时间戳等于当前时间戳减去开始计算时间然后左位移偏移量。偏移量等于12+5+5。
      • 机器码:-1L^(-1L <<5L),首先-1左移5位得到的结果再和-1异或计算,得到的结果是31,也就是5位能表达出的最大正整数。然后随机机器码再向左偏移12+5得到机器码。
      • 工作码:工作码和机器码类似,只是最后向左偏移量是5。
      • 序列码:序列是从0开始的自增序列,他是12位的最大整数 4095,从源码可以看出如果是同一毫秒,序列号要自增,如果是新的毫秒序列号要从0开始重新计算。sequence=(sequence+1)&sequenceMask可以保证不管sequence传入多少都能保证最后的结果小于4095,这样可以达到防溢出的效果。
    • 缺点:依赖服务器时间,id递增规律,可能因此泄漏商业机密(根据订单ID猜出订单量);长度长且固定,不容易加入自定义变量

    策略四:基于redis自增

    • 思路:利用增长计数API,结合其他信息组成唯一ID
    • Redis的 incr(key) API
    • 缺点:
      • 引入第三方依赖
      • 增加网络开销
      • 服务器成本、维护开销(redis高可用、集群)

    总结

    • 没有银弹,根据场景和需求选择合适的,满足KISS原则即可
  • 相关阅读:
    Java(15) _Runtime类 内存方法
    Mysql(1)_ 基本sql语句
    Java(13)_ 用IO流复制文件
    Java(12)_switch语句
    Java(10) _无参构造方法调用问题
    Java(9) _强制类型转换
    Java(8)_符串常量赋值
    Java(7)_file类的常用方法
    Java(6)_ Runtime类调用exe程序
    Java(5) _类的定义
  • 原文地址:https://www.cnblogs.com/wod-Y/p/12781906.html
Copyright © 2020-2023  润新知