推特雪花算法SnowFlake

1. 组成部分

SnowFlake算法用来生成64位的ID,刚好可以用long整型存储,能够用于分布式系统中生产唯一的ID, 并且生成的ID有大致的顺序。 在这次实现中,生成的64位ID可以分成5个部分:

0 - 41位时间戳 - 5位数据中心标识 - 5位机器标识 - 12位序列号

2. 各种常见唯一字符串优缺点

UUID(缺点:太长、没法排序、使数据库性能降低)
Redis(缺点:必须依赖Redis)(相当于使用中间件来获得ID)
Snowflake雪花算法,优点:生成有顺序的id,提高数据库的性能
效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。

3. 工具类代码Idworker.java


import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;/*** <p>名称:IdWorker.java</p>* <p>描述:分布式自增长ID</p>* <pre>*     Twitter的 Snowflake JAVA实现方案* </pre>* 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000* 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,* 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),* 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。* 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),* 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。* <p>* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))** @author Polim*/
public class IdWorker {// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)private final static long twepoch = 1288834974657L;// 机器标识位数private final static long workerIdBits = 5L;// 数据中心标识位数private final static long datacenterIdBits = 5L;// 机器ID最大值private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);// 数据中心ID最大值private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);// 毫秒内自增位private final static long sequenceBits = 12L;// 机器ID偏左移12位private final static long workerIdShift = sequenceBits;// 数据中心ID左移17位private final static long datacenterIdShift = sequenceBits + workerIdBits;// 时间毫秒左移22位private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;private final static long sequenceMask = -1L ^ (-1L << sequenceBits);/* 上次生产id时间戳 */private static long lastTimestamp = -1L;// 0,并发控制private long sequence = 0L;private final long workerId;// 数据标识id部分private final long datacenterId;public IdWorker(){this.datacenterId = getDatacenterId(maxDatacenterId);this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);}/*** @param workerId*            工作机器ID* @param datacenterId*            序列号*/public IdWorker(long workerId, long datacenterId) {if (workerId > maxWorkerId || workerId < 0) {throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));}if (datacenterId > maxDatacenterId || datacenterId < 0) {throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));}this.workerId = workerId;this.datacenterId = datacenterId;}/*** 获取下一个ID** @return*/public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));}if (lastTimestamp == timestamp) {// 当前毫秒内,则+1sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {// 当前毫秒内计数满了,则等待下一秒timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;// ID偏移组合生成最终的ID,并返回IDlong nextId = ((timestamp - twepoch) << timestampLeftShift)| (datacenterId << datacenterIdShift)| (workerId << workerIdShift) | sequence;return nextId;}private long tilNextMillis(final long lastTimestamp) {long timestamp = this.timeGen();while (timestamp <= lastTimestamp) {timestamp = this.timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}/*** <p>* 获取 maxWorkerId* </p>*/protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {StringBuffer mpid = new StringBuffer();mpid.append(datacenterId);String name = ManagementFactory.getRuntimeMXBean().getName();if (!name.isEmpty()) {/** GET jvmPid*/mpid.append(name.split("@")[0]);}/** MAC + PID 的 hashcode 获取16个低位*/return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);}/*** <p>* 数据标识id部分* </p>*/protected static long getDatacenterId(long maxDatacenterId) {long id = 0L;try {InetAddress ip = InetAddress.getLocalHost();NetworkInterface network = NetworkInterface.getByInetAddress(ip);if (network == null) {id = 1L;} else {byte[] mac = network.getHardwareAddress();id = ((0x000000FF & (long) mac[mac.length - 1])| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;id = id % (maxDatacenterId + 1);}} catch (Exception e) {System.out.println(" getDatacenterId: " + e.getMessage());}return id;}public static void main(String[] args) {IdWorker idWorker=new IdWorker(0,0);System.out.println((idWorker.nextId()+"").length());
//      for(int i=0;i<3000;i++){//          long nextId = idWorker.nextId();
//          System.out.println(nextId);
//      }}}

订单管理的订单号生成方式相关推荐

  1. 【SSM】第四课 超市订单管理平台--订单管理功能

    概念 本文在供应商管理功能之后,继续讲解订单管理功能,该功能是由普通员工与供应商之间的订单进货,经理进行监管等等. 需求分析 订单管理: 1.如果系统管理员登录,操作订单管理没有权限 2.如果经理登录 ...

  2. WMS仓库管理系统---(13)订单管理--创建订单

    订单模块可谓是WMS系统中最重要的一个模块,所有的业务开展都是围绕订单来运作的.订单模块也是系统中业务繁杂的一个模块,包括订单创建,订单审核,订单分配,订单拣货,订单打包,订单出库配送等各个环节,这一 ...

  3. 基于SSM+JSP实现的民宿预订网站(用户管理、房源管理、注册登录、民宿预定、订单管理、订单删除等)

    博客目录 基于SSM+JSP实现的民宿预订网站 实现功能截图 系统功能 使用技术 完整源码 基于SSM+JSP实现的民宿预订网站 本系统是SSM的民宿管理系统,可以实现用户管理.房源管理.用户注册登录 ...

  4. java连接销售订单查询_(三十一)订单管理-查询订单

    查询订单: 所有的订单 不区分用户 基本的sql select* from orders where 1=1判断是否有state 若有则添加state 最后order by ordertime des ...

  5. Django+Vue开发生鲜电商平台之10.购物车、订单管理和支付功能

    文章目录 一.购物车功能实现 1.加入购物车功能实现 2.修改购物车数量功能实现 3.和Vue结合实现购物车功能 二.订单功能实现 1.订单管理接口 2.Vue接入订单接口 三.支付宝支付接口完成 1 ...

  6. 医药/医疗/互联网医疗服务平台/问诊/挂号/开药/处方/医生/医院/问诊订单管理/移动端问诊医疗系统/医生端处方开药系统/web端医药服务平台管理/axure原型/rp源文件/健康咨询/视频问诊/统计

    医药/医疗/互联网医疗服务平台/问诊/挂号/开药/处方/医生/医院/问诊订单管理/移动端问诊医疗系统/医生端处方开药系统/web端医药服务平台管理/处方管理/axure原型/rp源文件/健康咨询/视频 ...

  7. 智慧电商erp通用版管理系统+采购管理+仓库管理+订单管理+财务管理+系统管理+Axure高保真交互ERP通用版电商web端管理系统+全局说明+竞品分析+协同办公

    作品介绍:智慧电商erp通用版管理系统+采购管理+仓库管理+订单管理+财务管理+系统管理+Axure高保真交互ERP通用版电商web端管理系统+全局说明+竞品分析+协同办公 原型交互及下载地址请点击: ...

  8. 快捷餐饮之店家后台订单管理实现

    j3_liuliang 上期写了餐桌及评论管理相关的功能,现在我们来实现一下订单管理相关内容 项目相关文章导航: 快捷点餐项目简介 餐饮系统设计概括 餐饮系统店家后端基础功能构建 快捷餐饮之店家后台O ...

  9. python订单管理系统功能_订单管理系统的基本功能有哪些?

    订单管理系统是通过统一的订单管理和分配,给用户提供整合的一站式供应链服务,让仓储,运输和订单形成一个有机的整体,从而满足物流信息化的需求,今天德米萨就给大家具体介绍下订单管理系统的基本功能有哪些. 1 ...

最新文章

  1. 深智云 让企业在物联网时代实现数据价值
  2. php mysql log文件,mysql log文件【读书笔记1】_MySQL
  3. Uboot启动全过程
  4. 使用MySQL的23个注意事项
  5. linq to sql报错,
  6. 服务器出生点配置文件,服务器设置出生点
  7. 优酷VIP被黑灰产恶意冒领出现BUG 用户疯抢一年VIP
  8. 压缩软件自动化测试,FOR…IN…ZIP循环——自动化测试精解(14)
  9. 网络地址转换 NAT
  10. 30岁前成功的12条黄金法则
  11. Python支持向量机(SVM)实例
  12. 【ML经典书籍系列1】解读PRML
  13. ARM Cortex-M3/M4内核相关
  14. 布同:如何循序渐进学习Python语言(转载)
  15. php必应壁纸 分辨率,Python爬取必应壁纸的代码实例
  16. mPass 微服务开发平台
  17. nuvoton uboo2013引导流程 2 - spl
  18. 1.1 LaTex中文环境搭建
  19. 重装解决一切 Linux:unknown filesystem
  20. 2018 ACM-ICPC青岛现场赛 B题 Kawa Exam 题解 ZOJ 4059

热门文章

  1. win2003修改Administrator用户名的方法
  2. 56_Django数据库_ORM外键删除操作详解
  3. linux下wxr的权限,Linux下的文件权限
  4. wal_level问题
  5. 钢琴学习:B站:时一:《周杰伦的《告白气球》真是百听不厌,5分钟教会你弹唱,一学便会》
  6. python语言不支持面向对象_Python 面向对象(初级篇)
  7. 爬虫工具-爬虫软件-免费爬虫工具软件
  8. JS split 分割字符串
  9. 关于JS中的prototype介绍
  10. Flutter键盘与同区域面板(如表情)无缝切换切换