Golang 一致性哈希负载均衡

1,644 阅读1分钟

这是我参与更文挑战的第18天,活动详情查看:更文挑战

如果❤️我的文章有帮助,欢迎点赞、关注。这是对我继续技术创作最大的鼓励。[更多系列文章在我博客] coderdao.github.io/

Golang 实现一致性哈希负载均衡

个人理解:一致性哈希算法

  • 根据每一台服务器不同的 ip:port 根据自己的key生成算法,生成一个唯一的 key 值
  • key => ip:port 把机器唯一的 key 映射机器访问地址 ip:port 设置到一个有序的循环圆
  • 请求过来的时候,根据请求内容生成按 自己的key生成算法 也生成一个 请求的key
  • 请求的key有序的循环圆 上 机器的 key 循环对比,第一个 机器的 key 大于 请求的key 就是最优解,由它来处理该请求
  • 如果 请求的key有序的循环圆 上 机器的 key 都大,那么由 圆上第一条机器处理
  • 有序的循环圆 上机器,根据访问情况。近实时增删机器映射

一致性哈希负载均衡 具体编码实现

图片描述

负载轮询测试代码

package load_balance

import (
	"fmt"
	"testing"
)

func TestNewConsistentHashBanlance(t *testing.T) {
	rb := NewConsistentHashBanlance(10, nil)
	rb.Add("127.0.0.1:2003") //0
	rb.Add("127.0.0.1:2004") //1
	rb.Add("127.0.0.1:2005") //2
	rb.Add("127.0.0.1:2006") //3
	rb.Add("127.0.0.1:2007") //4

	//url hash
	fmt.Println(rb.Get("http://127.0.0.1:2002/base/getinfo"))
	fmt.Println(rb.Get("http://127.0.0.1:2002/base/error"))
	fmt.Println(rb.Get("http://127.0.0.1:2002/base/getinfo"))
	fmt.Println(rb.Get("http://127.0.0.1:2002/base/changepwd"))

	//ip hash
	fmt.Println(rb.Get("127.0.0.1"))
	fmt.Println(rb.Get("192.168.0.1"))
	fmt.Println(rb.Get("127.0.0.1"))
}

测试结果

$ go test
2021/06/18 19:17:57 Failed to connect to 127.0.0.1:2181: dial tcp 127.0.0.1:2181: i/o timeout
err zk: could not connect to a server
127.0.0.1:2004 <nil>
127.0.0.1:2005 <nil>
127.0.0.1:2004 <nil>
127.0.0.1:2005 <nil>
127.0.0.1:2007 <nil>
127.0.0.1:2003 <nil>
127.0.0.1:2007 <nil>