GoLang分佈式鎖與snowflake雪花算法
go語言在網絡服務模塊有著得天獨厚的優勢;傳送門詳細介紹瞭涉及到的分佈式相關技術。
分佈式id生成器
Snowflake(雪花算法),由Twitter提出並開源,可在分佈式環境下用於生成唯一ID的算法。
生成的Id是64位(int64)數值類型,包含4部分:
- 41bit的時間戳(毫秒):一般是相對系統上線時間的毫秒數(可用69年);
- 5bit的數據中心id+5bit的機器id:表示工作的計算機;實際使用時可根據情況調整兩者間的比例;
- 12bit序列號:區分同一個計算機在相同毫秒時間內的生產的ID(支持1毫秒4096條);
github.com/bwmarrin/snowflake
提供瞭一個輕量級的實現:
package main import ( "fmt" "github.com/bwmarrin/snowflake" "time" ) func main() { n, err := snowflake.NewNode(time.Now().UnixMilli() % 1024) if err != nil { fmt.println(err) os.Exit(1) } for i := 0; i < 10; i++ { id := n.Generate() fmt.Println("id", id.Int64()) fmt.Println( "node: ", id.Node(), "step: ", id.Step(), "time: ", id.Time(), ) } }
分佈式鎖
可通過redis的setnx
來模擬分佈式鎖:
- 設定成功時,為上鎖;
- 釋放鎖時,刪除對應的鍵;
import ( "fmt" "sync" "time" "github.com/go-redis/redis" ) func incr() { client := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password set DB: 0, // use default DB }) var lockKey = "counter_lock" var counterKey = "counter" // lock resp := client.SetNX(lockKey, 1, time.Second*5) lockSuccess, err := resp.Result() if err != nil || !lockSuccess { fmt.Println(err, "lock result: ", lockSuccess) return } // counter ++ getResp := client.Get(counterKey) cntValue, err := getResp.Int64() if err == nil { cntValue++ resp := client.Set(counterKey, cntValue, 0) _, err := resp.Result() if err != nil { // log err println("set value error!") } } println("current counter is ", cntValue) // unlock delResp := client.Del(lockKey) unlockSuccess, err := delResp.Result() if err == nil && unlockSuccess > 0 { println("unlock success!") } else { println("unlock failed", err) } }
也可通過zookeeper或etcd來模擬;
負載均衡
從n個服務節點中,挑選一個的思路瞭:
- 按順序挑
- 隨機挑一個
- 根據某種權重,對節點進行排序,選擇權重最大/小的那一個
到此這篇關於GoLang分佈式鎖與snowflake雪花算法的文章就介紹到這瞭,更多相關GoLang分佈式鎖內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!