UUID订单单号生成器
UUID订单单号生成器
/** 订单号生成(NEW) **/
private static final AtomicInteger SEQ = new AtomicInteger(1000);
private static final DateTimeFormatter DF_FMT_PREFIX = DateTimeFormatter.ofPattern(“yyMMddHHmmssSS”);
private static ZoneId ZONE_ID = ZoneId.of(“Asia/Shanghai”);
public static String generateOrderNo(){
LocalDateTime dataTime = LocalDateTime.now(ZONE_ID);
if(SEQ.intValue()>9990){
SEQ.getAndSet(1000);
}
return dataTime.format(DF_FMT_PREFIX)+SEQ.getAndIncrement();
}
public static void main(String[] args) {List<String> orderNos = Collections.synchronizedList(new ArrayList<String>());IntStream.range(0,8000).parallel().forEach(i->{orderNos.add(generateOrderNo());});List<String> filterOrderNos = orderNos.stream().distinct().collect(Collectors.toList());System.out.println("生成订单数:"+orderNos.size());System.out.println("过滤重复后订单数:"+filterOrderNos.size());System.out.println("重复订单数:"+(orderNos.size()-filterOrderNos.size()));
}
我们的应用是跑在docker里面,而且每个docker容器内的应用端口都一样,不过网路IP不会存在重复的问题,至于进程也有存在重复的可能,对于UUID的方式之前吃过亏,总之吧,redis或DB也算是一种比较好的方式,不过独立性较差。。。
同时还有一个因素也很重要,就是所有涉及到订单号生成的应用都是在同一台宿主机(linux实体服务器)上, 所以就目前的系统架构我选用了IP的方式。
import org.apache.commons.lang3.RandomUtils;
import java.net.InetAddress;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class OrderGen2Test {
/** 订单号生成 **/
private static ZoneId ZONE_ID = ZoneId.of("Asia/Shanghai");
private static final AtomicInteger SEQ = new AtomicInteger(1000);
private static final DateTimeFormatter DF_FMT_PREFIX = DateTimeFormatter.ofPattern("yyMMddHHmmssSS");
public static String generateOrderNo(){LocalDateTime dataTime = LocalDateTime.now(ZONE_ID);if(SEQ.intValue()>9990){SEQ.getAndSet(1000);}return dataTime.format(DF_FMT_PREFIX)+ getLocalIpSuffix()+SEQ.getAndIncrement();
}private volatile static String IP_SUFFIX = null;
private static String getLocalIpSuffix (){if(null != IP_SUFFIX){return IP_SUFFIX;}try {synchronized (OrderGen2Test.class){if(null != IP_SUFFIX){return IP_SUFFIX;}InetAddress addr = InetAddress.getLocalHost();// 172.17.0.4 172.17.0.199 ,String hostAddress = addr.getHostAddress();if (null != hostAddress && hostAddress.length() > 4) {String ipSuffix = hostAddress.trim().split("\\.")[3];if (ipSuffix.length() == 2) {IP_SUFFIX = ipSuffix;return IP_SUFFIX;}ipSuffix = "0" + ipSuffix;IP_SUFFIX = ipSuffix.substring(ipSuffix.length() - 2);return IP_SUFFIX;}IP_SUFFIX = RandomUtils.nextInt(10, 20) + "";return IP_SUFFIX;}}catch (Exception e){System.out.println("获取IP失败:"+e.getMessage());IP_SUFFIX = RandomUtils.nextInt(10,20)+"";return IP_SUFFIX;}
}public static void main(String[] args) {List<String> orderNos = Collections.synchronizedList(new ArrayList<String>());IntStream.range(0,8000).parallel().forEach(i->{orderNos.add(generateOrderNo());});List<String> filterOrderNos = orderNos.stream().distinct().collect(Collectors.toList());System.out.println("订单样例:"+ orderNos.get(22));System.out.println("生成订单数:"+orderNos.size());System.out.println("过滤重复后订单数:"+filterOrderNos.size());System.out.println("重复订单数:"+(orderNos.size()-filterOrderNos.size()));
}
}
代码说明及几点建议
generateOrderNo()方法内不需要加锁,因为AtomicInteger内使用的是CAS自旋转锁(保证可见性的同时也保证原子性,具体的请自行了解)
getLocalIpSuffix()方法内不需要对不为null的逻辑加同步锁(双向校验锁,整体是一种安全的单例模式)
本人实现的方式并不是解决问题的唯一方式,具体解决问题需要视当前系统架构具体而论
任何测试都是必要的,我同事在前几次尝试解决这个问题后都没有自测,不测试有损开发专业性!
UUID订单单号生成器相关推荐
- vue前端自动生成编号或者订单单号(日期+随机数)
created () {// 调用获取当前日期的方法加四位随机数 赋值表单中的项目编号this.form.number = this.getProjectNum() + Math.floor(Math ...
- 高可用高性能可扩展的单号生成方案
作者:赵玉开,十年以上互联网研发经验,2013年加入京东,在运营研发部任架构师,期间先后主持了物流系统自动化运维平台.青龙数据监控系统和物流开放平台的研发工作,具有丰富的物流系统业务和架构经验.在此之 ...
- ecshop插件_ECSHOP和SHOPEX快递单号查询中通快递插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- ECSHOP快递单号查询插件圆通V8.2专版
本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅急送快递.德邦物流.百世快递.汇通快递.中通快递.天天快递等知 ...
- SHOPEX快递单号查询插件圆通V8.2专版
SHOPEX快递物流单号查询插件特色 本SHOPEX快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅急送快递.德邦物流.百世 ...
- ECSHOP和SHOPEX快递单号查询申通插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- ECSHOP和SHOPEX快递单号查询EMS插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- ECSHOP和SHOPEX快递单号查询韵达插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- ECSHOP和SHOPEX快递单号查询百世快递插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- ECSHOP和SHOPEX快递单号查询顺丰插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
最新文章
- mysql的优化之table_open_cache 篇_mysql性能优化之table_open_cache
- 解决vscode中golang插件依赖安装失败问题
- Markdown常用转义字符
- 壁纸图片|2020年12月游戏图片大全
- P1103 书本整理
- [转载] 将整数k转换成实数python表达式_Python程序设计课后习题答案-第一单元
- HBuilder搭建Android模拟器
- oracle sql语句_7个维度查看oracle执行计划的sql语句执行效率
- labview的初步
- 计算机无法识别语音输入,我的电脑每次启动语音识别总是显示“由于语言配置不受支持,无法启动语音识别”;...
- 迅雷手机版苹果版_IOS手机迅雷下载(支持苹果手机和ipad)
- rclone 实现 GoogleDrive 同步至 OneDrive
- 科大讯飞,百度,思必驰,云知声四款识别引擎降噪算法性能对比
- python中如何查一个函数的用法_Python常见内置函数用法(三)
- 大神F1 Plus和中兴V5s哪个好
- 拯救者R7000系列(AMD) win10+ubuntu20双系统安装笔记,解决显卡、亮度控制、触控板问题
- Mac系统下使用SecureCRT连接Linux虚拟机及上传文件
- Windows操作系统各版本的历史 Windows系统历史版本简介
- Unity接入苹果内购(IAP)
- 【Statistics】HYPOTHESIS TEST(SIGNIFICANCE TEST)