架构师_程序员

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 74|回复: 1

[交流] ID号生成 雪花算法

[复制链接]
跳转到指定楼层
楼主
发表于 5 天前
zu
Twitter的分布式雪花算法 SnowFlake 每秒自增生成26个万个可排序的ID
1、twitter的SnowFlake生成ID能够按照时间有序生成
2、SnowFlake算法生成id的结果是一个64bit大小的整数
3、分布式系统内不会产生重复id(用有datacenterId和machineId来做区分)
datacenterId(分布式)(服务ID 1,2,3.....) 每个服务中写死
machineId(用于集群) 机器ID 读取机器的环境变量MACHINEID 部署时每台服务器ID不一样

  1. /**
  2. * Twitter的分布式自增ID雪花算法snowflake
  3. * @author MENG
  4. * @create 2018-08-23 10:21
  5. **/
  6. public class SnowFlake {

  7.     /**
  8.      * 起始的时间戳
  9.      */
  10.     private final static long START_STMP = 1480166465631L;

  11.     /**
  12.      * 每一部分占用的位数
  13.      */
  14.     private final static long SEQUENCE_BIT = 12; //序列号占用的位数
  15.     private final static long MACHINE_BIT = 5;   //机器标识占用的位数
  16.     private final static long DATACENTER_BIT = 5;//数据中心占用的位数

  17.     /**
  18.      * 每一部分的最大值
  19.      */
  20.     private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
  21.     private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
  22.     private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);

  23.     /**
  24.      * 每一部分向左的位移
  25.      */
  26.     private final static long MACHINE_LEFT = SEQUENCE_BIT;
  27.     private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
  28.     private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;

  29.     private long datacenterId;  //数据中心
  30.     private long machineId;     //机器标识
  31.     private long sequence = 0L; //序列号
  32.     private long lastStmp = -1L;//上一次时间戳

  33.     public SnowFlake(long datacenterId, long machineId) {
  34.         if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
  35.             throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
  36.         }
  37.         if (machineId > MAX_MACHINE_NUM || machineId < 0) {
  38.             throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
  39.         }
  40.         this.datacenterId = datacenterId;
  41.         this.machineId = machineId;
  42.     }

  43.     /**
  44.      * 产生下一个ID
  45.      *
  46.      * @return
  47.      */
  48.     public synchronized long nextId() {
  49.         long currStmp = getNewstmp();
  50.         if (currStmp < lastStmp) {
  51.             throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
  52.         }

  53.         if (currStmp == lastStmp) {
  54.             //相同毫秒内,序列号自增
  55.             sequence = (sequence + 1) & MAX_SEQUENCE;
  56.             //同一毫秒的序列数已经达到最大
  57.             if (sequence == 0L) {
  58.                 currStmp = getNextMill();
  59.             }
  60.         } else {
  61.             //不同毫秒内,序列号置为0
  62.             sequence = 0L;
  63.         }

  64.         lastStmp = currStmp;

  65.         return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
  66.                 | datacenterId << DATACENTER_LEFT       //数据中心部分
  67.                 | machineId << MACHINE_LEFT             //机器标识部分
  68.                 | sequence;                             //序列号部分
  69.     }

  70.     private long getNextMill() {
  71.         long mill = getNewstmp();
  72.         while (mill <= lastStmp) {
  73.             mill = getNewstmp();
  74.         }
  75.         return mill;
  76.     }

  77.     private long getNewstmp() {
  78.         return System.currentTimeMillis();
  79.     }

  80.     public static void main(String[] args) {
  81.         SnowFlake snowFlake = new SnowFlake(1, 1);

  82.         long start = System.currentTimeMillis();
  83.         for (int i = 0; i < 1000000; i++) {
  84.             System.out.println(snowFlake.nextId());
  85.         }

  86.         System.out.println(System.currentTimeMillis() - start);


  87.     }
  88. }
复制代码






上一篇:asp.net core 写个中间件来记录接口耗时
下一篇:2019最新Java项目实战《谷粒商城》+某内java全套教程
帖子永久地址: 

架构师_程序员 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与架构师_程序员享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和架构师_程序员的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、架构师_程序员管理员和版主有权不事先通知发贴者而删除本文

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
沙发
发表于 昨天 09:55
这个牛逼`大名鼎鼎的雪花算法...
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。

Mail To:help@itsvse.com

QQ|Archiver|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2019-9-17 11:06

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表