Golang Snowflake
Snowflake - это сетевая служба для генерации уникальных идентификационных номеров в большом масштабе с некоторыми простыми гарантиями.
- Первый бит - это неиспользуемый знаковый бит.
- Вторая часть состоит из 41-битной отметки времени (миллисекунды), значение которой представляет собой смещение текущего времени относительно определенного времени.
- 10-битный идентификатор машины (5-битный рабочий идентификатор + 5-битный идентификатор центра обработки данных), максимальное значение - 2 ^ 10-1 = 1023.
- Последняя часть состоит из 12 битов, это означает длину серийного номера, генерируемого за миллисекунду на рабочий узел, максимум 2 ^ 12 -1 = 4095 идентификаторов могут быть сгенерированы за одну миллисекунду.
- Двоичная длина в 41 бит составляет не более 2 ^ 41-1 миллисекунду = 69 лет. Таким образом, алгоритм снежинки можно использовать до 69 лет. Чтобы максимально использовать алгоритм, вы должны указать время его запуска.
Не гарантируется, что идентификатор, сгенерированный алгоритмом снежинки, будет уникальным. Например, когда два разных запроса поступают на один и тот же компьютер в одно и то же время, и последовательность, сгенерированная узлом, одинакова, сгенерированный идентификатор будет дублироваться.
Поэтому, если вы хотите использовать алгоритм снежинки для генерации уникального идентификатора, вы должны убедиться: порядковый номер, сгенерированный в той же миллисекунде того же узла, является уникальным.
На основе этого мы создали этот пакет и интегрировали в него несколько поставщиков порядковых номеров.
- AtomicResolver
Каждому провайдеру нужно только убедиться, что серийный номер, сгенерированный за одну и ту же миллисекунду, отличается. Вы можете получить уникальный идентификатор.
Особенность
- ✅ Бесплатная блокировка
- 🎈 Нулевая конфигурация, из коробки
- 🚀 Безопасность параллелизма
- 🌵 Поддержка частного IP-адреса для machineid
- 🐡 Поддержка преобразователя пользовательской последовательности
Установка
go get github.com/godruoyi/go-snowflake
Использование
Простое использование.
package main
import (
"fmt"
"github.com/godruoyi/go-snowflake"
)
func main() {
id := snowflake.ID()
fmt.Println(id)
// 1537200202186752
}
С указанием MachineID.
package main
import (
"fmt"
"github.com/godruoyi/go-snowflake"
)
func main() {
snowflake.SetMachineID(1)
// Or set private ip to machineid, testing...
// snowflake.SetMachineID(snowflake.PrivateIPToMachineID())
id := snowflake.ID()
fmt.Println(id)
}
С указанием времени старта.
package main
import (
"fmt"
"time"
"github.com/godruoyi/go-snowflake"
)
func main() {
snowflake.SetStartTime(time.Date(2014, 9, 1, 0, 0, 0, 0, time.UTC))
id := snowflake.ID()
fmt.Println(id)
}
Как разобрать ID.
package main
import (
"fmt"
"time"
"github.com/godruoyi/go-snowflake"
)
func main() {
id := snowflake.ID()
sid := snowflake.ParseID(id)
fmt.Println(sid.ID) // 132271570944000000
fmt.Println(sid.MachineID) // 0
fmt.Println(sid.Sequence) // 0
fmt.Println(sid.Timestamp) // 31536000000
fmt.Println(sid.GenerateTime()) // 2009-11-10 23:00:00 +0000 UTC
}
Лучшие практики
⚠️⚠️ Весь метод SetXXX является потокобезопасным, рекомендуется вызывать его в основной функции.
package main
import (
"fmt"
"time"
"net/http"
"github.com/godruoyi/go-snowflake"
)
func main() {
snowflake.SetMachineID(1) // change to your machineID
snowflake.SetStartTime(time.Date(2014, 9, 1, 0, 0, 0, 0, time.UTC))
http.HandleFunc("/order", submitOrder)
http.ListenAndServe(":8090", nil)
}
func submitOrder(w http.ResponseWriter, req *http.Request) {
orderId := snowflake.ID()
// save order
}
Расширенный метод использования
Пользовательский преобразователь последовательностей. Вы можете настроить преобразователь порядковых номеров следующим образом:
package main
import (
"fmt"
"time"
"github.com/godruoyi/go-snowflake"
)
func yourSequenceNumber(ms int64) (uint16, error) {
}
// usage
snowflake.SetSequenceResolver(yourSequenceNumber)
snowflake.ID()