一. 分布式 id
特點:
1. 全局唯一性:全局沒有重復的id標識。
2. 遞增性:保證生成的 id 在業務中是遞增的。
3. 高可用:確保在任何時候都能生成正確可用的id。
4. 高並發:在高並發環境下表現良好。
分布式id常見解決方案
1. UUID
java 中自帶的算法,其能生成一串占 36 bit 的字符串,可以保證唯一性但無法實現有序遞增,且業務可讀性差。
2. 雪花算法
具體介紹寫在下面。
3. Leaf
由美團開源的分布式id生成算法,能保證唯一性,遞增性,但需要依賴關系數據庫、Zookeeper 等中間件。可以參考:Leaf算法
二. 雪花算法
雪花算法是 Twitter 開發的一種分布式 id 生成算法,即 SnowFlake 算法,取意於自然界不存在兩片完全一樣的雪花,雪花算法生成的 id 也如雪花一樣是獨一無二的。
組成
雪花算法生成的 id 是一個 64 bit(位)的 long 型的數字(二進制的),下面給出結構圖:
該生成的 id 主要由 4 部分構成:
1. 首位無效占位符:占用 1 bit ,其值始終為 0,沒有意義。
2. 時間戳:占用 41 bit ,用來記錄時間戳,為毫米級,即 2 的 41 次方大概為 69 年。
3. 機器編碼:占用 10 bit ,其中高位 5 bit 是數據中心 ID,低位 5 bit 是工作節點 ID,最多可以容納 1024 個節點。
4. 序列號:占用 12 bit ,用來記錄同毫秒內產生的不同 id 。每個節點每毫秒從 0 開始不斷累加,最多可以累加到 4095 ,一共可以產生 4096 個 id 。
SnowFlake算法在同一毫秒內最多可以生成 1024 X 4096 = 4194304 個全局唯一id。
三. 雪花算法導致前端精度丟失解決方法
原因:
前端 js 的 number 類型有最大值,即 2 的 53 次方,為9007199254740992,這是一個 16 位的十進制整數即前端精度為 16 位,后端采用雪花算法得到的 id 是 long 型(64 bit)的即精度為 19 位。這時候,前后端傳值就會出現精度丟失。
解決方法:
1.把數據庫 id 改為 String 類型,相當的麻煩,且性能會下降,此種方法不能使用。
2.采用注解方法,將@JsonSerialize(using = ToStringSerializer.class)
加到需要的 id 字段上。例子如下:
public class ArticleVo {
//防止后端Long類型轉為前端JSON數據精度丟失
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
private String title;
private String summary;
}
3.可以采用這個博主的全局配置類方法:點擊這里查看