1、分布式集群架構
2、分布式高並發環境的訂單號要求
- 全局唯一
- 訂單號信息要安全
- 趨勢遞增
3、訂單號生成策略總結
策略 | 優點 | 缺點 | 格式 |
---|---|---|---|
uuid | 實現簡單不占用帶寬 | 無序、不可讀、查詢慢 | 32位 |
db自增 | 無代碼、遞歸 | DB單點故障、擴展有瓶頸 | |
snowflake | 不占用帶寬、低位趨勢遞增 | 依賴服務器時間 | 18位 |
redis | 無單點故障、性能優於DB遞增 | 占用帶寬、Redis集群需要維護 | 12位 |
3.1、策略一:UUID(通用唯一識別碼)
組成:當前日期+時間+時鍾序列+機器識別號(MAC地址或其他)
分布式系統中,所有元素(web服務器)都不需要通過中央控制端來判斷數據唯一性。
3.2、策略二:數據庫自增ID
關系型數據庫都實現數據庫自增ID;mysql通過auto_increment實現、oralce通過sequence實現。
在數據庫集群環境下,不同數據庫節點可設置不同起步值、相同步長值來實現集群下生成全局唯一、遞增ID。
3.3、策略三:snowflake算法
組成:41位時間戳+10為機器ID+12位序列號(自增),轉換位長度為18的長整型。
twitter位滿足每秒上萬條消息的創建,每條消息都必須分配全局唯一id,這些id要趨勢遞增,方便客戶排序。
github上可以下載到snowflake源碼
3.4、策略四:Redis自增ID
- redis的api: incr(key) 若key存在,則將key的value遞增1並返回,如果key不存在則將改key對應的value初始化為0並返回。
- 自增格式:前綴+自增id 。
- 超時時間:使用超時時間是為了防止自增到9999時訂單號的位數變長。
public class RedisUtil {
@Autowired
JedisPool jedisPool;
public long getIncr(String key, int timeout) {
Jedis redis = null;
try {
redis = jedisPool.getResource();
// 當key不存在時,創建一個值為0的key
long id = redis.incr(key);
if (timeout > 0) {
// 設置超時時間
redis.expire(key, timeout);
return id;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (redis != null) {
redis.close();
}
}
return -1;
}
}