如何设计一个能扛住双11并发的订单号生成方案

2024-02-11 18:58

本文主要是介绍如何设计一个能扛住双11并发的订单号生成方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

要设计订单号首先需要订单号应该要具备的一些特性:

  1. 唯一性:这绝对是作为订单号最最最基本的特点;

  2. 高并发:并发能力越高越好;

  3. 趋势递增但是不能绝对递增:趋势递增会对现代数据库索引结构更友好,但是不要绝对递增是因为绝对递增的话,很容易暴露你系统每天产生的订单量;

  4. 利于以后的分库分表;

我的订单号方案

技术方案:
timestamp + 类用户ID + 随机数(可选)实现代码:
Long userId = 235689102L;
String last6 = userId<1000000?String.format("%06d", userId):String.valueOf(userId%1000000);
String orderId = System.currentTimeMillis() + last6;

这种方案是否具备上面提到的几个特点呢,让我们一起看一看:

  1. 唯一性:这种方案的订单号只有在同一个用户在同一毫秒内下多个订单才会出现出现,很显然,对于正常的用户行为,是不可能出现重复的,所以满足唯一性。

  2. 高并发:这个设计方案完全不依赖任何第三方服务,只通过一定的规则就能生成。所以这种方案不但高并发,而且零消耗。

  3. 递增性:因为订单号的前一部分是时间戳,所以满足趋势递增。并且,也满足非绝对递增的特性。

  4. 分库分表:假设分库分表因子为订单号最后6位数,那么无论是根据订单ID查询,还是根据用户ID查询,都不会涉及跨库跨表,效率非常高。至于根据商户编号查询商户的订单号,可以参考笔者另一篇文章《分库分表技术演进&最佳实践-修订篇》,有提到解决方案。

通过上面的分析可知,这种方案还是很不错的!而且,这种方案不需要依赖任何第三方服务,需要的硬件成本为零,老板最喜欢呀!当然,如果担心用户ID信息通过订单号暴露,可以先通过某种函数例如hash(userId),然后再生成订单号即可。伪代码如下:

Long userId = 235689102L;
Long hashId = hash(userId);
String last6 = hashId<1000000?String.format("%06d", hashId):String.valueOf(hashId%1000000);
String orderId = System.currentTimeMillis() + last6;
System.out.println(orderId);

 

  • 为什么这种方案利于分库分表?

我们知道作为一个订单表,最核心的查询有3类:根据订单号查询、根据用户ID查询、根据商户号查询,这三类查询占了订单表90%甚至更多的查询量。如果采用的是这里提到的时间戳+类用户ID的方案,那么根据订单号查询和根据用户ID查询都不涉及跨表,效率非常高。请看接下来的分析。

假设订单表按照订单号进行分表,并且分表算法为:hash(last6(orderId))%16,即根据订单号的最后6位数字hash后取模。这样的话,如下几个订单号就会分在同一个表假设t_order_5中,因为这几个订单号最后6位数字完全一样:

1573172799123 141618
1575878423467 141618
1583545280012 141618

然后,这几个订单表都是用户ID为182141618生成的(我们假设hash(182141618)%1000000=141618)。那么用户ID为182141618所生成的订单也会都落在表t_order_5中,因为hash(182141618)%1000000=141618,也就是说,查询条件带有userId=182141618的查询目标表都是t_order_5。事实上,这种方案就是所谓的因子分表法

接下来,我们可以看一下支付宝订单号又是如何设计的。

 

支付宝订单号方案

下面是3个真实的支付宝订单号(空格是为了更直观的看出支付宝订单号的特点):

20191024 2200141625 1404175790
20191025 2200141625 1404414662
20191026 2200141625 1405369921

分析这几个支付宝订单号,我们将其分解为3部分,从而得出支付宝的订单号的特点。你的支付宝订单号同样具备这样的特点:

时间戳 + 类用户ID + 递增的数值

通过对支付宝订单号的分解,我们很容易发现它的方案和前面提到的方案有异曲同工之妙:都有时间戳部分和类用户ID部分,此乃英雄所见略同也,哈哈哈!

这篇关于如何设计一个能扛住双11并发的订单号生成方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/700577

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri