`
annan211
  • 浏览: 448322 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

高并发生成订单号(二)

 
阅读更多

银联16位数字订单号
永远不重复的生成算法

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1
1、 前提背景
相信做过银联支付的都知道,银联的订单号要求商户提供一个不重复的16位数字订单号(不重复指的是对商户本身,不用考虑银联有多个商户会与其他商户的订单号重复)。16位数其实很短,要考虑每秒并发1w或者10w或100万时,重复订单号将数不过来。
需要考虑的因素:
 若使用数据库保存流水号,集群部署时,同步关键字不再有效。当然同步对性能也有非常大的影响;
 若使用时间,必须要精确到毫秒、微妙级别,长度就不止16位了。
 若使用数据库字段自增,数据库并发时硬件将吃不消。
 获取订单号时检查表的最大值,这种方案是最不可取的。

以下将给出本人经过深入研究的三种方案,按顺序,最优的方案为第三个。
备注:
如果要测试产生重复订单号的情况,可以建立一个表,把订单号字段设置为唯一性,然后开启1000或10000或更多的线程去请求方法,每个线程循环5次或10次来请求,在方法里面写插入语句。或者可以使用Apache的ab工具并发测试。
使用方法:ab -n5000 -c5000 http://192.168.1.102:8888/kjcx/aaa.action

2、 可选方案一
本方案使用的是当前时间,包括毫秒数、纳秒数,不需要数据库参与计算,性能不用说。
算法:

OrderId=
machineId+
(System.currentTimeMillis()+"").substring(1)+
(System.nanoTime()+"").substring(7,10);


讲解:
参数machineId:是集群时的机器代码,可以1-9任意。部署时,分别为部署的项目手动修改该值,以确保集群的多台机器在系统时间上不一致的问题(毫无疑问每台机器的毫秒数基本上不一致)。
参数System.currentTimeMillis():这是java里面的获取1970年到目前的毫秒数,是一个13位数的数字,与Date.getTime()函数的结果一样,比如1378049585093。经过研究,在2013年,前三位是137,在2023年是168,到2033年才199.所以,我决定第一位数字1可以去掉,不要占位置了。可以肯定绝大多数系统用不了10年20年。这样,参数2就变成了12位数的数字,加上参数1machineId才13位数。
参数System.nanoTime():这是java里面的取纳秒数,经过深入研究,在同一毫秒内,位置7,8,9这三个数字是会变化的。所以决定截取这三个数字出来拼接成一个16位数的订单号。
总结:理论上此方案在同一秒内,可以应对1000*1000个订单号,但是经过测试,在每秒并发2000的时候,还是会出现2-10个重复。

3、 可选方案二
本方案使用的是获得会话ID(sessionId)来产生hashCode。
算法:

OrderId=
machineId+
session().getId().hashCode();


讲解:
参数machineId不再讲解,与方案一致。
参数2 session().getId().hashCode()是值在web系统中获取用户浏览器与web容器的唯一会话编号,再把该会话ID转换为该字符串的hashCode值,如1939354961。该值可能是一个11位数的或10位数的,或者在前面还会出现-号,也就是有可能该值是负数,没关系,取正。然后再对该值进行左补0到15位数,基本上可以应对位数不一致的问题。
我们知道,hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值。可以想象,hashCode的值如果出现重复,那就是一个值了,而不是不同的值。又因为sessionId是客户端、与浏览器有关联的,所以基本上不会出现重复,但是如果用户在同一个会话有效期内、同一个版本的浏览器,生成2次就无效了,因为会话ID是一致的。
总结:该算法,可以确保不重复的概率很小,但是需要自己特殊处理同会话同浏览器生成1次以上订单号的问题,此算法没有经过调试,略过,您请看方案三。

4、 可选方案三
本方案在基于方案二的基础上做了修改,使用的使用UUID而不是会话id。
UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,这个不重复性全世界人民都知道。当然,既然字符串值不重复,那对应的hashCode也是一样,不会重复。
算法:

OrderId=
machineId+
UUID.randomUUID().toString().hashCode();



讲解:
参数1不再解释。
参数2是值生成UUID然后取它的hashCode值,经过测试,完全没有一点问题。您可以开1000w的并发去测试插入吧,只要数据库不会报唯一性错误,那就没问题。
总结:
hashCode这个算法从搞软件开始到现在这么多年,一直没派上用场,这次大大的用上了。解决了问题。请同志们以后善用这个东西。
5、 附录:方案三的算法代码

6、	public static String getOrderIdByUUId() {
7、			int machineId = 1;//最大支持1-9个集群机器部署
8、			int hashCodeV = UUID.randomUUID().toString().hashCode();
9、			if(hashCodeV < 0) {//有可能是负数
10、				hashCodeV = - hashCodeV;
11、			}
12、			// 0 代表前面补充0     
13、			// 4 代表长度为4     
14、			// d 代表参数为正数型
15、			return machineId+String.format("%015d", hashCodeV);
16、		}



方案三其实也就一个函数,很简便。

最后:这是引自一个未知人的思想,不记得他的地址了。

 

分享到:
评论
3 楼 dida1990 2017-05-02  
啊喔,过去了这么久,不过还是评一个。
谁说uuid的hashCode不重复的啊,明显还是有可能重复,不然你去看看string的hashCode源码
2 楼 annan211 2017-01-02  
yclovesun 写道
使用了uuid,为什么还要machineId?uuid已经可以保证不重复了啊

  UUID理论上是不会重复,但是考虑到严格性和确保不重复,需要格外处理。
1 楼 yclovesun 2016-12-23  
使用了uuid,为什么还要machineId?uuid已经可以保证不重复了啊

相关推荐

    跨境电子商务客户服务:认识卖家服务等级.pptx

    认识卖家服务等级 《跨境电子商务客户服务》 目录 李晓运营速卖通店铺 情景描述 收到了客户对商品描述准确性的评价 任务导入 李晓想知道: 任务操作 店铺评分 商品描述的准确性 ...买家选择卖家原因并成功取消订单

    人工智能与智能制造V2.pdf

    精益 效率 质量 成本 成品入库 关键控制点岗位监控 包装QC 远程SOP巡检 信息传递直接 减少沟通成本 车间绩效考核 辅助5S执行 问题的历史真相 销售订单号:XXXXXXX 生产领料 生产过程可视化监管 11 防静电车间/高粉尘...

    FOXPHP开源威客系统 v3.01.zip

    资金流向等详细记录,并与订单关联,可以追踪到某个任务上。 交易金额的来龙去脉一目了然。 4.强大 编辑器 默认使用 百度编辑 优化改进版本,批量上传图片;上传文件等并显示进度。 并提高用户上传图片附件的操作...

    网吧设计方案.doc

    网吧设计方案 学 院:电子与信息工程学院 学生姓名: 专业班级:09计算机网络技术3班 学 号: 指导教师:徐文义 完成日期:2010年9月 目 录 摘 要 I 第一章 绪 论 1 1.1 概述 1 1.2 网吧背景 1 1.3 项目建设的必要性...

    程序文件-----产品召回控制程序.doc

    要求零售商通过批号/订单号,生产日期和入库日期等立即查询该批产品的 " "剩余库存数量,已分发正在使用和未使用完的该批产品批量,并立即回收, " "和剩余库存一起封存等待集中回收。 " "e.产品召回后采取适当的...

    按摩连锁财务管理系统 v1.0.zip

    这样会极大的减轻了店内的系统维护工作,也降低了系统发生故障的可能性。   进入系统详细功能: (1)系统设置 参数设置 备份数据 用户管理 添加用户 来源类型 添加类型 项目管理 添加项目 支付管理 ...

    大型正式B2C商业购物系统

    [需提供订单编号和用户帐号] 3、用户再最后支付时,可选择不同的支付方式,将看到不同的信息。 4、用户可以随时找回密码,密码将发送到其注册时候填写的信箱。 5、完善的商品管理功能。 可以任意 添加、删除、...

    eas供应链dep案例集

    新增及调整字段 EASSCMA1P0005 销售订单中增加订单时间、发货时间、交货时间并精确到分秒 精细化工行业对销售订单中所涉及到的时间要求非常精确,如要求订单日期、发货日期、交货日期要精确到分钟。现有的销售订单...

    电商“双十一”营销调研报告.doc

    名: 学 号: 时 间: 2016年11月18日 2016年度 良品铺子 电商 "双十一"营销活动调研报告 实验一 选择某电商平台"双十一"、"双十二"营销活动实践,进行全程跟踪,针对其营 销方案及实施细节进行综合分析并形成...

    梁佑E1服装制衣鞋帽打菲(打飞)记菲计件工资管理软件 打菲领导者

    3、 为管理者提供工序工价的拟定依据,掌握制单生产进度,监控车间运作情况,按制单号、扎号及工序编制工菲,并可分行打印输出 ,有效杜绝偷菲、自编菲的事情发生,提供计件工资报表,员工发放的客观依据 ,准确快捷...

    梁佑E1服装制衣鞋帽/打菲软件/计件工资管理软件 打菲记件领导者

    3、 为管理者提供工序工价的拟定依据,掌握制单生产进度,监控车间运作情况,按制单号、扎号及工序编制工菲,并可分行打印输出 ,有效杜绝偷菲、自编菲的事情发生,提供计件工资报表,员工发放的客观依据 ,准确快捷...

    PetShop4.0宠物商店+系统架构设计+中文注释源码+PDF中文详解

    其中包括“添加一张新订单”的方法Insert()和根据一个已有的订单号取得此订单详细信息的方法GetOrder(),此方法返回的是一个OrderInfo对象。(Model中的OrderInfo类模型定义了用户的某一张Order中相关的信息,如发货...

    阿里巴巴编码规范 基础技能认证 考题分析(考题+答案).docx

    关于二方库版本号的命名方式,下列哪些说法符合《阿里巴巴Java开发手册》:ABCD A .版本号命名格式:主版本号.次版本号.修订号。 B .主版本号:产品方向改变,或者大规模API不兼容,或者架构不兼容升级。 C .次...

    数据库主键设计原则.txt

    第二:对于象订单这样的有主外键的表来说,如果订单的"主档表"主键是自动生成的. 那么在保存一个订单时,会要求对主档表与明细表同进行事务保存,而此时,先要生成一条订单,然后取出这个订单自动生成的主键, 然后再把此...

    ISO900-程序文件-采购控制程序.doc

    5.6订单内容变更 5.6.1 如因业务需求订单需发生变化时, 采购人员应迅速与供货商协调更改交期、交货量等相关事宜。 5.6.2 供货商无法满足订单内容, 本公司可视情况取消订单或其它处理。 5.6.3 订单确认后, 若厂商遭...

    热泵行业经销商合作协议

    4.1 定货时,乙方应提前15天向甲方下书面订单(传真件有效),订货单应由乙方法人代表签字并加盖公章。每份订货单均构成一份独立的购销协议,该订单自甲方收到乙方货款时生效,本协议的所有条款为该订单的当然条款...

Global site tag (gtag.js) - Google Analytics