diff --git a/examples/owner_id_generator/main.go b/examples/owner_id_generator/main.go new file mode 100644 index 0000000..c73cc8d --- /dev/null +++ b/examples/owner_id_generator/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + storage_lock "github.com/storage-lock/go-storage-lock" +) + +func main() { + + generator := storage_lock.NewOwnerIdGenerator() + ownerId := generator.GenOwnerId() + fmt.Println(ownerId) + // Output: + // storage-lock-owner-id-DESKTOP-PL5RI7C-72c2cd2add88b29799e2f2646be16131-1-541201dd0eee40bba0f956ddce427f7c + +} diff --git a/owner_id_generator.go b/owner_id_generator.go index c51116e..f269262 100644 --- a/owner_id_generator.go +++ b/owner_id_generator.go @@ -1,6 +1,8 @@ package storage_lock import ( + "crypto/md5" + "encoding/hex" "fmt" goroutine_id "github.com/golang-infrastructure/go-goroutine-id" "github.com/storage-lock/go-utils" @@ -9,13 +11,14 @@ import ( "strings" ) -// OwnerIdGenerator 当没有指定锁的持有者的ID的时候,自动生成一个ID +// OwnerIdGenerator 可以使用这个工具类来生成全局唯一的OwnerID // 1. 要满足全局唯一不重复 // 2. 可读性尽量好一些 type OwnerIdGenerator struct { defaultLockPrefix string } +// NewOwnerIdGenerator 创建一个OwnerID生成器 func NewOwnerIdGenerator() *OwnerIdGenerator { prefix := generateMachineDefaultLockIdPrefix() // 不能太长,不然存储和索引啥的费事 @@ -28,8 +31,8 @@ func NewOwnerIdGenerator() *OwnerIdGenerator { } } -// 这个方法应该具有幂等性,同一个goroutine应该恒返回同一个ID -func (x *OwnerIdGenerator) getDefaultOwnId() string { +// GenOwnerId 这个方法应该具有幂等性,同一个goroutine应该恒返回同一个ID +func (x *OwnerIdGenerator) GenOwnerId() string { // 这里为了可读性并没有将区分度最高的UUID放在前面,这是假设使用此分布式锁的各个竞争者的Hostname基本都不会相同 // 因为是同一台机器上使用分布式锁不是很有意义 return fmt.Sprintf("%s-%s-%s", x.defaultLockPrefix, goroutine_id.GetGoroutineIDAsString(), utils.RandomID()) @@ -42,16 +45,17 @@ func generateMachineDefaultLockIdPrefix() string { return "" } - macAddresses := strings.Builder{} + parts := make([]string, 0) + parts = append(parts, "storage-lock-owner-id") // 主机名 hostname, _ := os.Hostname() if hostname != "" { - macAddresses.WriteString(hostname) - macAddresses.WriteString("-") + parts = append(parts, hostname) } // MAC地址 + macAddresses := strings.Builder{} for index, netInterface := range netInterfaces { macAddr := netInterface.HardwareAddr.String() if len(macAddr) == 0 { @@ -62,7 +66,10 @@ func generateMachineDefaultLockIdPrefix() string { macAddresses.WriteString(",") } } - macAddresses.WriteString("-") + h := md5.New() + h.Write([]byte(macAddresses.String())) + macMd5 := hex.EncodeToString(h.Sum(nil)) + parts = append(parts, macMd5) - return macAddresses.String() + return strings.Join(parts, "-") } diff --git a/owner_id_generator_test.go b/owner_id_generator_test.go new file mode 100644 index 0000000..2e17040 --- /dev/null +++ b/owner_id_generator_test.go @@ -0,0 +1,23 @@ +package storage_lock + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestOwnerIdGenerator_GenOwnerID(t *testing.T) { + generator := NewOwnerIdGenerator() + + ownerIdSet := make(map[string]struct{}, 0) + for i := 0; i < 1000; i++ { + + ownerId := generator.GenOwnerId() + + _, exists := ownerIdSet[ownerId] + assert.False(t, exists) + ownerIdSet[ownerId] = struct{}{} + + assert.NotEmpty(t, ownerId) + t.Log(ownerId) + } +}