上一篇 <<<基于Twitter的snowflake(雪花)算法實現(xiàn)全局ID
下一篇 >>>服務注冊拣帽、服務發(fā)現(xiàn)和服務治理
方法一:預先生成
1皂股、提前生成一批訂單號放在redis中丙唧,每次使用的時候取一個办桨,當庫里沒有了,再生成一批
2垢箕、使用的時候前面用系統(tǒng)時間戳划栓,后面加上redis中取得的數(shù)據(jù)即可。
方法二:利用redis的自增
因為Redis是單線的条获,天生保證原子性忠荞,可以使用Redis的原子操作 INCR和INCRBY來實現(xiàn)
優(yōu)點
不依賴于數(shù)據(jù)庫,靈活方便帅掘,且性能優(yōu)于數(shù)據(jù)庫委煤。
數(shù)字ID天然排序,對分頁或者需要排序的結果很有幫助修档。
缺點
如果系統(tǒng)中沒有Redis碧绞,還需要引入新的組件,增加系統(tǒng)復雜度吱窝。
需要編碼和配置的工作量比較大讥邻。
注意:在Redis集群情況下,同樣和Redis一樣需要設置不同的增長步長院峡,同時key一定要設置有效期
》可以使用Redis集群來獲取更高的吞吐量兴使。假如一個集群中有5臺Redis≌占ぃ可以初始化每臺Redis的值分別是1,2,3,4,5发魄,然后步長都是5。各個Redis生成的ID為:
A:1,6,11,16,21
B:2,7,12,17,22
C:3,8,13,18,23
D:4,9,14,19,24
E:5,10,15,20,25
比較適合使用Redis來生成每天從0開始的流水號俩垃。比如訂單號=日期+當日自增長號欠母』恫撸可以每天在Redis中生成一個Key,使用INCR進行累加赏淌。
如果生成的訂單號超過自增增長的話,可以采用前綴+自增+并且設置有效期
設置有效期可統(tǒng)計當天的數(shù)據(jù)量啄清,
eg:2019010409552100001六水、2019010409552100002、2019010409552200003辣卒、2019010409552300004
2019010509552100001掷贾、2019010509552100002、2019010509552200003荣茫、2019010509552300004
代碼示例:
@RestController
public class OrderController {
@Autowired
private RedisTemplate redisTemplate;
/**
* timeOut一般設置為24小時想帅,則次日會從0重新開始計算
*/
@RequestMapping("/order")
public String order(String key, Long timeOut) {
RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
//設置起始值
// redisAtomicLong.set(1);
// 設置redis步長增長為2
redisAtomicLong.addAndGet(1);
// for (int i = 0; i < 100; i++) {
long andIncrement = redisAtomicLong.getAndIncrement();
//設置5位,不夠則前面補零
String orderId = prefix() + String.format("%1$05d", andIncrement);
String insertSQL = "insert into orderNumber value('" + orderId + "');";
// System.out.println(Thread.currentThread().getName() +
// ",insertSQL:" + insertSQL);
System.out.println(insertSQL);
if ((null == redisAtomicLong || redisAtomicLong.longValue() == 0) && timeOut > 0) {// 初始設置過期時間
redisAtomicLong.expire(timeOut, TimeUnit.SECONDS);
}
// }
return "success";
}
public static String prefix() {
String temp_str = "";
Date dt = new Date();
// 最后的aa表示“上午”或“下午” HH表示24小時制 如果換成hh表示12小時制
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
temp_str = sdf.format(dt);
return temp_str;
}
public static void main(String[] args) {
System.out.println(prefix());
}
}
推薦閱讀:
<<<分布式全局ID生成總覽
<<<基于數(shù)據(jù)庫自增方式實現(xiàn)全局ID
<<<基于UUID算法實現(xiàn)全局ID
<<<基于Twitter的snowflake(雪花)算法實現(xiàn)全局ID