电商网站中生成订单号的正确方式

好久没写博客啦,前段时间备案网站一直处于关闭状态。顺便吐槽下,为什么备案需要关站,我觉得打开才对嘛,这样才能核实信息才对。

开始正文

一般我们生成订单号有以下几种方式

一.利用数据库的自增主键来生成唯一ID

二.使用时间戳,加上毫秒,甚至微秒。如果订单交易频率实在很高再加上一个随机数。

三.利用UUID、GUID生成唯一订单号。

……..

这几种方案的缺点

第一种,利用数据库解决,显而易见的是效率瓶颈,每次生成都有IO操作,IO是非常开销是非常巨大的,高峰期的时候完全承受不住。

第二种,虽然存在一定的互斥行为,抢同一订单号,虽然情况很少但是还是存在这些情况。

第三中,虽然解决了唯一但是并没有解决可读性问题。

我的方案

利用依靠redis内存数据库来解决这些问题,redis 中有个incr命令,该命令每次执行的时候都会对指定的KEY 的值进行加+1操作,而且是原子性的。这样每次调用命令生成的订单号都是不相同,但是这种方案还是有个缺点,很容易暴露系统的交易情况,猜出下一个订单号。我们可以在这基础上进行扩展,随机生成订单号,写入Redis,然后每次使用的时候进行获取操作,这样保证了订单号的随机性。 并且Redis可以将内存数据异步写入到磁盘中,避免单例服务器宕机的情况下依然可以从磁盘中恢复。

安装redis扩展

Mac OS X

brew install homebrew/php/php56-redis

代码实现

<?php
/**
 * Created by PhpStorm.
 * User: xiaoxingxing
 * Date: 2016/11/27
 * Time: 上午1:07
 */
//生产订单号
$redis = new Redis();//安装Redis扩展
$redis->connect("127.0.0.1");//建立连接
$date = date('Ymd');//订单号前缀,使用日期标识
$range_arr = range(1,100);//产生100个KEY数组
shuffle($range_arr);//数组打乱
foreach ($range_arr as $k=>$v) {//遍历插入
    $order_id = $date.str_pad($v,5,0,STR_PAD_LEFT);
    $redis->rPush('order_id',$order_id);// order_id  value1 value2
}
echo "Success";
<?php
/**
 * Created by PhpStorm.
 * User: xiaoxingxing
 * Date: 2016/11/27
 * Time: 上午10:37
 */
//消费订单号
$redis = new Redis();
$redis->connect("127.0.0.1");
$order_id = $redis->lPop('order_id');//移除并获取一个元素。
echo $order_id;
此条目发表在php语言分类目录,贴了标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注