订单号唯一的一种解决方案

目前,比较火的nosql数据库,如MongoDB,Redis,Riak都提供了类似incr原子行操作。

下面是PHP版的一种实现方式:

 1 <?php
 2 /**
 3  * 基于Redis的全局订单号id
 4  *
 5  * @author liujingyu
 6  * @copyright liujingyu, 11 八月, 2014
 7  **/
 8
 9 class OrdersnumAction {
10
11     private $_r;
12     private $_host;
13     private $_port;
14     private $_passwd;
15     private $_prefix;
16     private $_len;
17
18     function __construct() {
19
20         try {
21
22             $redisconfig = array(
23                 ‘host‘=>‘xx.x.xx.x‘,
24                 ‘port‘=>6379,
25                 ‘password‘=>‘xxxxxxxxxxxxxx‘,
26                 ‘prefix‘=>‘order_num‘,
27                 ‘len‘=>6,
28             );
29
30             $this->setBuilder($redisconfig);
31
32             $this->_r = new redis;
33             $ret = $this->_r->connect($this->_host, $this->_port);
34             if (!$ret) {
35                 die("[redis connect error]");
36             }
37             $this->_r->auth($this->_passwd);
38         }
39         catch (Exception $e) {
40             trace($e->getMessage());
41         }
42     }
43
44     private function setBuilder($redisconfig) {
45
46         $this->_host = $redisconfig[‘host‘];
47         $this->_port = $redisconfig[‘port‘];
48         $this->_passwd = $redisconfig[‘password‘];
49         $this->_prefix = $redisconfig[‘prefix‘];
50         $this->_len    = $redisconfig[‘len‘];
51     }
52
53     /**
54      * 生成当天全局唯一自增id
55      *
56      * @param integer $key
57      *
58      * @return $id
59      * @author liujingyu
60      **/
61     private function nextId($key) {
62         $id = $this->_r->incr($this->_prefix.":".$key);
63         $l = strlen($id);
64         if ($l>$this->_len) {
65             return $id;
66         } else {
67             return str_repeat(0, $this->_len-$l).$id;
68         }
69     }
70
71     /**
72      * 获取订单号
73      *
74      * @return integer
75      * @author liujingyu
76      **/
77     public function getOrdersNum() {
78
79         $key = date(‘ymd‘, time());
80         return $key.$this->nextId($key);
81     }
82 }

采用的Redis中incr原子操作,并发量7w(单机,2核,2GB,centos6.5)。

类似天猫双十一这样的电商,提高并发量采用Redis list类型预生成,hash取模分散到多个实例中。进而达到无限扩展容。

时间: 2025-01-05 13:57:44

订单号唯一的一种解决方案的相关文章

分布式系统订单号唯一策略

1.分布式集群架构 2.分布式高并发环境的订单号要求 全局唯一 订单号信息安全要求 趋势递增要求 3.订单号生成策略总结 策略 优点 缺点 格式 uuid 实现简单不占用带宽 无序.不可读.查询慢 32位 db自增 无代码.递归 DB单点故障.扩展有瓶颈 snowflake 不占用带宽.低位趋势递增 依赖服务器时间 18位 redis 无单点故障.性能优于DB递增 占用带宽.Redis集群需要维护 12位 3.1.策略一:UUID(通用唯一识别码) 组成:当前日期+时间+时钟序列+机器识别号(M

mysql使用触发器生成唯一订单号,

需求:订单号唯一,并且期望是时间格式加其他字符串, 实现:采用触发机制,在新增时根据新增id值加1作为订单生成的随机且确定唯一的数,因为id唯一: 遇到问题:新增时不能提前知道id值, 解决:取到当前表中最大值+1即为id: 业务需要研究几个小时终于实现一套可行方案: 代码: 建表 DROP TABLE IF EXISTS `qs_test`; CREATE TABLE `qs_test` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `ord

订单号生成规则

前阵子,公司有个电子商务项目,需要生成订单号.当时的考虑很简单,取系统时间加上随机数,或者使用 uniqid() 方法.我们都知道,订单号最基本的要求就是唯一,这个条件必须满足.仔细考虑下上述方法,在顾客购买量少的情况下,订单重复的可能性为零,但是在购买高蜂期生成的订单号重复是很有可能发生的.所以上述方法不可靠,有待强化.在网上找了一番,发现这位同学的想法挺不错的,redtamo,具体的请稳步过去看看,我作简要概述,该方法用上了英文字母.年月日.Unix 时间戳和微秒数.随机数,重复的可能性大大

php生成唯一订单号

支持更改长度/** * 生成唯一订单号 * */ function build_order_no(){ return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8); }

两个PHP方面的东西,超过2038的时间和唯一订单号算法

2014年10月01日  php开发 1条评论 阅读264次 DateTime::format 被设计成不受外部设置影响(面向对象就应该如此)所以无论你如何改变环境参数 date_default_timezone ,都不会影响输出结果要想改变 DateTime::format 的时区设置,需要向 DateTime::setTimezone 传入一个时区对象 DateTimeZone 1 $d = new DateTime('@2444486400'); 2 $d->setTimezone(new

如何生成唯一订单号(转)

首先,订单号有3个性质:1.唯一性 2.不可推测性 3.效率性 唯一性和不可推测性不用说了,效率性是指不能频繁的去数据库查询以避免重复.况且满足这些条件的同时订单号还要足够的短.我在java下定制的订单号生成方式如下:int r1=(int)(Math.random()*(10));//产生2个0-9的随机数int r2=(int)(Math.random()*(10));long now = System.currentTimeMillis();//一个13位的时间戳String paymen

c#唯一订单号生成代码

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string uniqueNum = GenerateOrderNumber(); Console.WriteLin

c# asp.net 生成唯一订单号

c# asp.net 生成唯一订单号 string OrderNo = DateTime.Now.Year.ToString().Substring(2, 2) + DateTime.Now.Month.ToString().PadLeft(2, '0') + DateTime.Now.Day.ToString().PadLeft(2, '0') + DateTime.Now.Hour.ToString().PadLeft(2, '0') + DateTime.Now.Minute.ToStri

PHP生成唯一的订单号

记:之前面试的时候被面试官问过简历项目中的订单号我是什么规则生成的,我牛逼吹过头了,乱说了一通,靠!今天在公司的项目中订单号生成,好奇,看了下,就是网上的这种而已. 1 * 2 * uniqid - 官方是这样说的: 3 * Gets a prefixed unique identifier based on the current time in microseconds. 4 */ 5 function build_order_no() 6 { 7 return date('Ymd').su