1. 程式人生 > 其它 >雪花演算法分散式Id以及其產生的前端精度損失解決方法

雪花演算法分散式Id以及其產生的前端精度損失解決方法

一. 分散式 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.可以採用這個博主的全域性配置類方法:點選這裡檢視