业务流水号(交易号)生成方法

概述


大流量下订单号生成方法一文中介绍了如何生成不重复的订单号,主要原理是利用数据库自增ID。但是像业务流水号之类的,其实不利用数据库也是可以的,只是要保证唯一性,做起来不太好做。下文介绍一种方法来生成流水号,如果不是那种特别变态的调用量,产生重复的机会还是很少的。但是如果是那种无论如何都不能重复的,不建议用本文的方法了。


流水号生成规则


时间+四位的机器号+10位的随机数


时间的生成

时间的话,可以使用下面的方式来生成。

FastDateFormat.getInstance("yyyyMMddHHmmssSSS").format(new Date()))

使用apache的FastDateFormat线程安全的格式化时间,到毫秒。注意千万别用JAVA自带的SimpleDateFormat,不是线程安全的,如果你一定要用SimpleDateFormat的话,需要结合ThreadLocal来实现。


机器号

这个可以先用JAVA代码获取机器的MAC地址。如何获取机器的MAC地址的代码,网上大把,这里贴一个用过的。

private static String getMacAddress() throws Exception {
		Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
		while (networkInterfaces.hasMoreElements()) {
			NetworkInterface networkInterface = networkInterfaces.nextElement();
			if (null == networkInterface) {
				continue;
			}
			byte[] macBytes = networkInterface.getHardwareAddress();
			if (networkInterface.isUp() && !networkInterface.isLoopback() && null != macBytes && macBytes.length == 6) {
				StringBuilder sb = new StringBuilder();
				for (int i = 0, nLen = macBytes.length; i < nLen; i++) {
					byte b = macBytes[i];
					sb.append(Integer.toHexString((b & 240) >> 4));
					sb.append(Integer.toHexString(b & 15));
					if (i < nLen - 1) {
						sb.append("-");
					}
				}
				return sb.toString().toUpperCase();
			}
		}
		return null;
	}

上面的代码就获取到MAC地址,格式是:

xx-xx-xx-xx-xx-xx

得到MAC地址后,可以根据MAC地址获取它对应的CRC16校验码,可以简单的使用如下代码来获取:

private static int getCRC16Code(String macAddress) {
		if (null == macAddress) {
			return 0;
		}
		byte[] data = macAddress.getBytes(Charset.forName("utf-8"));
		CRC16 crc16 = new CRC16();
		for (byte b : data) {
			crc16.update(b);
		}
		return crc16.value;
	}

接下来可以根据这个CRC16校验码截取高四位。这个代码比较简单,就不贴了。

另外,也见过机器号是通过环境变量来读取的,把机器号配置在环境变量中,然后直接在代码里读取。也见过在配置中心配置的。


生成随机数

可以利用JAVA的AtomicInteger来生成。


总结


如果你的应用是要给对方提供流水号的,那么如果对方使用for循环并且并发调用,还是有可能生成重复的流水号的,这种情况下,最好在客户端调用的时候,在for循环里sleep 一毫秒,降低并发。

另外有个建议,如果是对方的接口要求你传入一个唯一的流水号,最好在生成的流水号上加上自己系统的名字,这样服务方也可以通过看流水号,就知道是哪个系统过来的。


2018 博客之星


我最近在参与CSDN的博客之星评选,希望您投下宝贵的一票,多多支持我继续写博客,谢谢。

CSDN 2018博客之星,需要您投上宝贵的一票

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值