mirror of
https://github.com/godruoyi/go-snowflake.git
synced 2025-12-23 05:25:15 +00:00
🚛 first commit
This commit is contained in:
187
readme.md
Normal file
187
readme.md
Normal file
@@ -0,0 +1,187 @@
|
||||
<div>
|
||||
<p align="center">
|
||||
<image src="https://www.pngkey.com/png/full/105-1052235_snowflake-png-transparent-background-snowflake-with-clear-background.png" width="250" height="250">
|
||||
</p>
|
||||
<p align="center">An Lock Free ID Generator for Golang based on Snowflake Algorithm (Twitter announced).</p>
|
||||
<!-- <p align="center">
|
||||
<a href="https://scrutinizer-ci.com/g/godruoyi/go-snowflake/">
|
||||
<image src="https://scrutinizer-ci.com/g/godruoyi/go-snowflake/badges/quality-score.png?b=master" alt="quality score">
|
||||
</a>
|
||||
<a href="https://github.com/godruoyi/go-snowflake">
|
||||
<image src="https://github.styleci.io/repos/201936013/shield?branch=master" alt="godruoyi go-snowflake">
|
||||
</a>
|
||||
<a href="https://github.com/godruoyi/go-snowflake">
|
||||
<image src="https://poser.pugx.org/godruoyi/go-snowflake/license" alt="License">
|
||||
</a>
|
||||
<a href="https://packagist.org/packages/godruoyi/go-snowflake">
|
||||
<image src="https://poser.pugx.org/godruoyi/go-snowflake/v/stable" alt="Packagist Version">
|
||||
</a>
|
||||
<a href="https://scrutinizer-ci.com/g/godruoyi/go-snowflake/">
|
||||
<image src="https://scrutinizer-ci.com/g/godruoyi/go-snowflake/badges/build.png?b=master" alt="build passed">
|
||||
</a>
|
||||
<a href="https://github.com/godruoyi/go-snowflake">
|
||||
<image src="https://poser.pugx.org/godruoyi/go-snowflake/downloads" alt="Total Downloads">
|
||||
</a>
|
||||
</p> -->
|
||||
</div>
|
||||
|
||||
## Description
|
||||
|
||||
An Lock Free ID Generator for Golang implementation.
|
||||
|
||||

|
||||
|
||||
Snowflake is a network service for generating unique ID numbers at high scale with some simple guarantees.
|
||||
|
||||
* The first bit is unused sign bit.
|
||||
* The second part consists of a 41-bit timestamp (milliseconds) whose value is the offset of the current time relative to a certain time.
|
||||
* The 10 bits machineID, and max value is 2^10 -1 = 1023.
|
||||
* The last part consists of 12 bits, its means the length of the serial number generated per millisecond per working node, a maximum of 2^12 -1 = 4095 IDs can be generated in the same millisecond.
|
||||
* The binary length of 41 bits is at most 2^41 -1 millisecond = 69 years. So the snowflake algorithm can be used for up to 69 years, In order to maximize the use of the algorithm, you should specify a start time for it.
|
||||
|
||||
> You must know, The ID generated by the snowflake algorithm is not guaranteed to be unique.
|
||||
> For example, when two different requests enter the same machine at the same time, and the sequence generated by the node is the same, the generated ID will be duplicated.
|
||||
|
||||
So if you want use the snowflake algorithm to generate unique ID, You must ensure: The sequence-number generated in the same millisecond of the same node is unique.
|
||||
Based on this, we created this package and integrated multiple sequence-number providers into it.
|
||||
|
||||
* AtomicResolver (base sync/atmoic)
|
||||
* Custom (you can custom)
|
||||
|
||||
> Each provider only needs to ensure that the serial number generated in the same millisecond is different. You can get a unique ID.
|
||||
|
||||
## Installation
|
||||
|
||||
```shell
|
||||
$ go get github.com/godruoyi/go-snowflake
|
||||
```
|
||||
|
||||
## Useage
|
||||
|
||||
1. simple to use.
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/godruoyi/go-snowflake"
|
||||
)
|
||||
|
||||
func main() {
|
||||
id := snowflake.ID()
|
||||
fmt.Println(id)
|
||||
// 1537200202186752
|
||||
}
|
||||
```
|
||||
|
||||
2. Specify the MachineID.
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/godruoyi/go-snowflake"
|
||||
)
|
||||
|
||||
func main() {
|
||||
snowflake.SetMachineID(1)
|
||||
id := snowflake.ID()
|
||||
fmt.Println(id)
|
||||
}
|
||||
```
|
||||
|
||||
3. Specify start time.
|
||||
|
||||
```go
|
||||
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)
|
||||
}
|
||||
```
|
||||
|
||||
4. Parse ID.
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/godruoyi/go-snowflake"
|
||||
)
|
||||
|
||||
func main() {
|
||||
id := snowflake.ID()
|
||||
sid := snowflake.ParseID(id)
|
||||
|
||||
fmt.Println(sid.ID) //
|
||||
fmt.Println(sid.MachineID) //
|
||||
fmt.Println(sid.Sequence) //
|
||||
fmt.Println(sid.Timestamp) //
|
||||
fmt.Println(sid.GenerateTime()) //
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
> ⚠️⚠️ All SetXXX method is thread-unsafe, recommended you call him in the main function.
|
||||
|
||||
```go
|
||||
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
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced
|
||||
|
||||
1. Custom sequence resolver.
|
||||
|
||||
You can customize the sequence-number resolver by following way:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/godruoyi/go-snowflake"
|
||||
)
|
||||
|
||||
func yourSequenceNumber(ms int64) (uint16, error) {
|
||||
|
||||
}
|
||||
|
||||
// usage
|
||||
|
||||
snowflake.SetSequenceResolver(yourSequenceNumber)
|
||||
snowflake.ID()
|
||||
```
|
||||
|
||||
And you can use closure:
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user