diff --git a/pkg/hash-ring/define.go b/pkg/hash-ring/define.go index 50f14db..e3d4b88 100644 --- a/pkg/hash-ring/define.go +++ b/pkg/hash-ring/define.go @@ -1,12 +1,63 @@ package hashring +import ( + "sort" +) + type RingInterface interface { // 获取一个 远程连接用的目标 - GetTarget(key string) (*target, error) + GetTarget(key string) (*Target, error) // 获取下一个目标 - NextTarget(*target) (*target, error) + NextTarget(*Target) (*Target, error) // 获取上一个目标 - PreTarget(*target) (*target, error) + PreTarget(*Target) (*Target, error) +} + +/** +获取一个 远程连接用的目标 +*/ +func GetTarget(key string) string { + var clusterHash map[int]string = createClusterHashRing() + /* + 对集群key值从小到大排序 + */ + var sortHash []int + for hash := range clusterHash { + sortHash = append(sortHash, hash) + } + /** + 放入一个值 + */ + var keys = key + var hashKey int = int(getHash(keys)) + /** + 建立映射关系 + */ + var hashValue = make(map[int]string) + for value := range clusterHash { + hashValue[value-hashKey] = clusterHash[value] + } + var hashMap []int + for k := range hashValue { + hashMap = append(hashMap, k) + } + sort.Ints(hashMap) + var ip string + var flag int = 0 + for hash := range hashMap { + if hashMap[hash] > 0 { + ip = hashValue[hashMap[hash]] + return ip + } + flag++ + } + /** + 若找不到离最近的环,则返回第一个环 + */ + if flag == len(hashMap) { + ip = clusterHash[sortHash[0]] + } + return ip } diff --git a/pkg/hash-ring/load.go b/pkg/hash-ring/load.go index e109d8a..4fcc4c9 100644 --- a/pkg/hash-ring/load.go +++ b/pkg/hash-ring/load.go @@ -1,9 +1,52 @@ package hashring -type target struct { +type Target struct { + address []string } -func (t *target) GetAddrString() string { +func (t *Target) GetAddrString() []string { // TODO 获取负载机器地址 - return "" + return t.address +} + +func addAddrString(addrss []string) *Target { + return &Target{ + address: addrss, + } +} + +/** +构建hash环 +*/ +func createClusterHashRing() map[int]string { + var servers = [...]string{"192.168.0.0:111", "192.168.0.1:111", + "192.168.0.2:111", "192.168.0.3:111", "192.168.0.4:111"} + var clusterHash map[int]string + clusterHash = make(map[int]string) + for i := 0; i < len(servers); i++ { + var hash = int(getHash(servers[i])) + clusterHash[hash] = servers[i] + } + return clusterHash +} + +/** +使用FNV1_32_HASH算法计算服务器的Hash值 +*/ +func getHash(key string) int32 { + var p int32 = 16777619 + var hash int32 = -2128831035 + for i := 0; i < len(key); i++ { + hash = (hash ^ int32(key[i])) * p + } + hash += hash << 13 + hash ^= hash >> 7 + hash += hash << 3 + hash ^= hash >> 17 + hash += hash << 5 + if hash < 0 { + return -hash + } else { + return hash + } }