javaweb系统在高并发下怎样实现订单号生成少数

javaweb系统在高并发下可以用以下方法实现订单号生成少数:1、UUID;2、数据库自增;3、雪花算法;4、分布式组件。UUID 是Universally Unique Indentifier的缩写,翻译为通用少数识别码,UUID 的标准形式包含 32 个 16 进制数字,以连字号分为五段。

1、UUID

UUID 是Universally Unique Indentifier的缩写,翻译为通用少数识别码,顾名思义 UUID 是一个用于记录少数标识一条的数据,其按照开放软件基金会(OSF)指定的标准进行计算,用到了以太网卡地址(MAC)、纳秒级时间、芯片 ID 码和许多可能的数字。

总的来说,UUID 码由以下三部分组成:

  • 当前日期和时间
  • 时钟序列
  • 全局少数的 IEEE 机器识别码(如果有网卡从网卡获得,没有网卡则通过其他方式获得)

UUID 的标准形式包含 32 个 16 进制数字,以连字号分为五段,示例:00000191-adc6-4314-8799-5c3d737aa7de

java为例,通过以下方式即可生成:

String uuid = UUID.randomUUID().toString();

这种方案,虽然实现简单、方便;但是数据库查询效率非常差,而且内容长,在实际的项目场景开发中,一般用于于记录用户的手机设备ID等硬件信息!

2、数据库自增

所谓数据库自增,意思是在数据库中给某个列设置为自增列,并且给该列设置一个初始值,代码层面无需任何特殊处理,以 Mysql 的用户表 ID 列为例,可以通过如下方式在创建表的时候生产。

CREATE TABLE `tb_user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

这种通过数据库自增方式实现少数值,在单体服务下是没有问题,但是在大流量分布式服务环境下,并发性能很低。

3、雪花算法

Snowflake(中文简称:雪花算法) 是 Twitter 内部的一个 ID 生算法,可以通过一些简单的规则保证在大规模分布式情况下生成少数的 ID 号码。其内部结构如下:

javaweb系统在高并发下怎样实现订单号生成少数

可以很清晰的看出,Snowflake 由 4个部分组成:

  • 名列前茅部分:bit 值,为未使用的符号位
  • 第二部分:由 41 位的时间戳(毫秒)构成,它的取值是当前时间相对于某一时间的偏移
  • 第三部分:表示工作机器 id,由服务节点 id 和数据中心 id 组合而成
  • 第四部分:表示每个工作机器每毫秒生成的序列号 ID,同一毫秒内非常多可生成生产 4095 个 ID。

由于在 Java 中 64bit 的整数是 long 类型,因此在 Java 中 SnowFlake 算法生成的 id 就是 long 来存储的。

SnowFlake 算法可以保证:

  • 1.所有生成的 id 按时间趋势递增
  • 2.整个分布式系统内不会产生重复id(因为有服务节点 id 和数据中心 id 来做区分)

需要注意的是:

  • 在分布式环境中,5 个 bit 位的 datacenter 和 worker 表示非常多能部署 31 个数据中心,每个数据中心非常多可部署 31 台节点。
  • 41 位的二进制长度非常多能表示2^41 -1毫秒即 69 年,所以雪花算法非常多能正常使用 69 年,为了能最大限度的使用该算法,在使用的时候,应该为其指定一个开始时间,不然会发生重复!

在高并发的环境下,Snowflake 算法可以生成全局少数的订单编号,但是他的长度达到21,因此不推荐采用,但是可以用它来生成主键 ID,是完全没有问题的!

4、分布式组件

要想在分布式环境下生成一个少数的订单编号,我们可以通过分布式组件的方式,来帮忙我们生成全局少数的订单号,例如我们可以采用 redis 分布式缓存组件中的incr命令,来帮我们生成一个全局自增长的序列号!

实现逻辑如下:

//基于某个key实现自增长
String res = jedis.get(key);
if (StringUtils.isBlank(res)) {
    jedisClient.set(key, INIT_ID);//设置自增长的初始值,INIT_ID 是初始值
    jedisClient.expire(key, seconds);//设置过期时间,seconds 是多少秒过期
}
long orderId = jedis.incr(key);//存在就生成+1的订单号

这种方式生成的自增长序列号,非常的快,可以很好的满足大流量环境下的编号要求少数的特性!

剩下的主要工作就是我们如何去设计一个订单号规则!

实现过程如下:

//获取当前时间
Date currentTime  = new Date();
//格式化当前时间为【年的后2位+月+日】
String originDateStr = new SimpleDateFormat("yyMMdd").format(currentTime );
//计算当前时间走过的秒
Date startTime =  new SimpleDateFormat("yyyyMMdd").parse(new SimpleDateFormat("yyyyMMdd").format(originDate));
long differSecond = (currentTime.getTime() - startTime.getTime()) / 1000;
//获取【年的后2位+月+日+秒】,秒的长度不足补充0
String yyMMddSecond = originDateStr +  StringUtils.leftPad(String.valueOf(differSecond), 5, '0');

//获取【业务编码】 + 【年的后2位+月+日+秒】,作为自增key;
String prefixOrder = sourceType + "" + yyMMddSecond;
//通过key,采用redis自增函数,实现单秒自增;不同的key,从0开始自增,同时设置60秒过期
Long incrId = redisUtils.saveINCR(prefixComplaint, 60);
//生成订单编号
String orderNo = prefixOrder + StringUtils.leftPad(String.valueOf(incrId), 4, '0');

此订单编号可以保证大流量环境下全局少数、生成速度非常的快、支持高并发环境,同时还支持按时间排序

作者:程序员志哥
链接:https://www.zhihu.com/question/21128632/answer/2293633424
来源:知乎

延伸阅读

订单命名的几种规则

  • 不重复:必须全局少数
  • 安全性:订单号需要做到不容易被人为的猜测或者推测出来,例如订单号就是流水号的话,那么别人就很容易从订单号推测出公司的整体运营情况。
  • 禁用随机码:很多人分析生成订单号的时候,名列前茅个念头肯定是不重复少数性,那么第二个念头可能就是安全性,想要同时满足前两者,很容易想到使用随机码,随机码从一定程度来说,更安全、不重复性更高,但是可读性差,有概率会发生重复。
  • 防止并发:针对系统的并发业务场景(如秒杀),需要做到并发场景下,订单编号生成快速、不重复等要求
  • 控制位数:订单号的位数尽量在 10 位 ~ 18 位之间。太短的情况下,如果交易量过大,很难做到防止重复,太长可读性差、意义也不大。

文章标题:javaweb系统在高并发下怎样实现订单号生成少数,发布者:小编,转载请注明出处:https://worktile.com/kb/p/37388

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小编小编认证作者
上一篇 2023年2月7日 下午11:10
下一篇 2023年2月8日 上午11:13

相关推荐

  • oa资源主要有哪些类型

    OA资源包含期刊、数据库、学位论文、会议记录、技术报告、预印本、教科书、多媒体材料1、开放获取图书馆及其他学术内容。其中,期刊归类中,开放获取期刊特别受到重视,因为它们能够无缴费条件为广泛受众提供最新研究成果。 开放获取期刊提供最新的学术研究成果,并有着推动学科发展的作用。这类期刊无需通过传统订阅方…

    2024年1月11日
    31600
  • devops指标是什么

    开门见山地说,DevOps指标乃是衡量开发与运营合作效能的关键参量,归纳起来主要包括1、部署频率、2、变更前置时间、3、服务恢复时间、及4、变更失败率。部署频率特别值得深入探讨,它直接反映了软件交付的速度和团队响应市场变化的能力。一个高效的DevOps团队能够实现快速、持续的代码部署,从而快速迭代产…

    2024年3月26日
    6300
  • 规划部门如何管理项目经验

    在管理项目经验方面,规划部门通常采取以下措施:建立经验库、定期复盘、跨部门沟通与合作、尽早介入项目规划。规划部门通过建立一个经验库,可以有效地收集并整理项目中的成功经验和失败教训,为后续的项目工作提供参考。建立经验库是一个动态的过程,不断地将新的项目经验集成进去,特别是针对各种问题和解决方案的记录,…

    2024年4月10日
    5500
  • oa系统 公司

    OA系统是企业组织中关键的信息化管理平台,集成多种办公自动化功能,强调提升工作效率、促进信息共享、实现业务流程优化。1.提升通信效率、2.优化流程管理、3.强化信息安全、4.扩展移动办公,这些构成OA系统的主要价值所在。在第一点提升通信效率方面,OA系统通过内置邮箱、即时通讯、公告板等工具,对员工间…

    2024年1月17日
    16400
  • vscode为什么没有运行按钮

    Visual Studio Code (VSCode) 没有直接的运行按钮主要是因为它是一个轻量级代码编辑器,而不是一个完整的集成开发环境(IDE)。VSCode的设计理念、插件系统、以及其对多种编程语言的支持方式,旨在使它成为一个高度可扩展和个性化的工具。尤其是它的插件系统,为用户提供了极大的灵活…

    2024年4月3日
    14100
  • 如何开展工程项目检查管理

    工程项目检查管理是确保项目按计划、标准和质量要求顺利进行的关键环节。关键步骤包括建立检查标准、制定检查流程、运用检查工具、实施定期和不定期检查、检查结果分析、以及采取纠正措施。在这些步骤中,建立检查标准尤为重要,因为它提供了评价工程项目的绩效和质量的具体标准。通过与国际和国内法规、行业标准以及公司内…

    2024年4月10日
    4300
  • devops工程师改造什么序列

    标题:DevOps工程师如何改造工作流程 摘要:DevOps工程师改造工作流程关键在于1、施行自动化策略 2、增进团队沟通 3、采用敏捷实践 4、保障质量与安全措施融合 5、持续监控与反馈。这些策略优化了软件开发与运维方面的交互,提升了作业效率并缩减了产品上线周期。施行自动化策略是改造的重点,它包括…

    2024年3月26日
    7000
  • 如何在DevOps中实现高效的代码合并

    在DevOps领域,确保代码合并流程的效率和稳定性对于实现快速迭代和持续交付至关重要。1) 创建清晰的分支策略、2) 实施持续集成、3) 自动化测试、4) 规范代码审查、5) 利用可视化工具加强流程管理是相关的关键措施。在这些策略中,创建清晰的分支策略可以说是基础,它能有效地组织和管理各个开发阶段的…

    2024年1月2日
    25000
  • oa流程是什么

    OA流程指的是办公自动化系统(Office Automation System)的操作流程,该系统旨在通过信息技术改善办公效率和效果。1、该流程主要涉及文档的创建、编辑、共享和管理;2、内部通信和协作工具的应用;3、信息的存储与检索;4、任务和项目管理等应用功能。信息的存储与检索功能是流程中的关键因…

    2024年1月11日
    68700
  • mysql索引怎么建立

    在MySQL中建立索引主要涉及以下几个方面:1、理解索引的作用和类型;2、使用CREATE INDEX语句创建索引;3、在CREATE TABLE语句中定义索引;4、使用ALTER TABLE修改索引;5、索引的维护和优化。下文将详细介绍这些方法的使用和特点。 1、理解索引的作用和类型 索引用于提高…

    2023年8月17日
    34800

发表回复

登录后才能评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部