golang 实现负载均衡器-增加移除服务器方法代码实现以及其他优化-2.2-xunznux

go 实现负载均衡器代码细节

代码实现

gitee链接

原理介绍

原理介绍

版本1.0

版本1.0 demo实现

版本2.0

为了实现main函数等待所有其他协程执行完毕后再结束,使用了 sync.WaitGroup。WaitGroup是一个同步原语,它等待一组操作完成。你可以通过调用Add方法来增加计数,然后在协程中调用Done方法来减少计数,最后调用Wait方法来阻塞直到计数归零。
版本2.0
版本2.1

8、修改BalancerManager变量的作用域以及AddServer方法

为了后面更加方便的增加、移除节点,修改服务器列表变量的作用域。

// BalancerManager 管理负载均衡器和服务器列表。
// 它封装了负载均衡器的实例和服务器列表,提供了获取、添加和删除服务器的方法。
type BalancerManager struct {
	LoadBalancerInstance LoadBalancer   // 当前使用的负载均衡器实例
	Servers              []*server.Node // 服务器列表
}

// AddServer 向服务器列表中添加一个新服务器。
func (lbm *BalancerManager) AddServer(server *server.Node) {
	// 向服务器列表中追加新服务器
	lbm.Servers = lbm.LoadBalancerInstance.AddServer(lbm.Servers, server)
}

9、增加移除物理服务器节点的方法

首先需要修改 LoadBalancer 接口,增加RemoveServer方法:

type LoadBalancer interface {
	// SelectServer 是 LoadBalancer 接口的核心方法,它接收一个服务器列表作为参数,
	// 并从中选择一个服务器返回其地址。如果服务器列表为空,应该返回一个错误。
	// SelectServer 函数接受一个 ...interface{} 类型的参数,这样你就可以选择性地传递 data 参数。当没有提供 data 参数时,data 将是一个空的切片,可以检查其长度或者第一个元素是否为 nil 来判断是否提供了数据
	SelectServer(servers []*server.Node, data ...interface{}) (*server.Node, error)
	// AddServer 函数用于向负载均衡器中添加服务器。
	AddServer(servers []*server.Node, server *server.Node) []*server.Node
	RemoveServer(servers []*server.Node, server *server.Node) []*server.Node
}
load_balancer_manager 中增加RemoveServer方法:
// RemoveServer 从服务器列表中移除一个服务器。
// 如果服务器不存在于列表中,该方法不会产生任何效果。
func (lbm *BalancerManager) RemoveServer(server *server.Node) {
	lbm.Servers = lbm.LoadBalancerInstance.RemoveServer(lbm.Servers, server)
}
一致性散列算法:

一致性哈希策略这里增加一个 RemoveNodes 方法用于将虚拟节点从哈希环移除。

// RemoveNodes 将虚拟节点从哈希环移除
func (c *ConsistentHash) RemoveNodes(nodes ...*server.Node) {
	for _, node := range nodes {
		// 每个真实的服务器节点都要创建 replicas 个虚拟节点
		for i := 0; i < c.replicas; i++ {
			// 对每一个真实节点 key,对应创建 c.replicas 个虚拟节点,虚拟节点的名称是:
			// strconv.Itoa(i) + key,即通过添加编号的方式区分不同虚拟节点
			hash := int(c.hash([]byte(node.NodeIpAddr + "_" + strconv.Itoa(i) + node.Port)))
			// 使用 c.hash() 计算虚拟节点的哈希值,使用 append(c.keys, hash) 添加到环上。
			for j, r := range c.hashRing {
				if r == hash {
					c.hashRing = append(c.hashRing[:j], c.hashRing[j+1:]...)
				}
			}
			// 在 virtualNodeMap 中增加虚拟节点和真实节点的映射关系。
			delete(c.virtualNodeMap, hash)
		}
	}
	// 最后一步,环上的哈希值排序。
	sort.Ints(c.hashRing)
}

增加一个 RemoveServer 方法移除服务器节点,实际上只是将服务器的状态改为不可用。

// RemoveServer 移除服务器节点
func (c *ConsistentHash) RemoveServer(servers []*server.Node, server *server.Node) []*server.Node {
	c.mu.Lock()

	// 遍历服务器列表,查找并移除指定的服务器
	for _, s := range servers {
		if s.NodeId == server.NodeId {
			// 移除找到的服务器
			//servers = append(servers[:i], servers[i+1:]...)
			s.Status = 0
			c.RemoveNodes(server)
			break
		}
	}
	c.mu.Unlock()

	return servers
}
加权轮询算法:

加权轮询算法中,移除节点后需要及时更新权重节点列表。

// RemoveServer 移除服务器节点
func (w *WeightedRoundRobin) RemoveServer(servers []*server.Node, server *server.Node) []*server.Node {
	w.mu.Lock()

	// 遍历服务器列表,查找并移除指定的服务器
	for _, s := range servers {
		if s.NodeId == server.NodeId {
			// 移除找到的服务器
			//servers = append(servers[:i], servers[i+1:]...)
			s.Status = 0
			break
		}
	}
	w.mu.Unlock()
	
    // 通过通道通知进行服务器节点权重列表的更新
	w.detectServersChan <- servers
	return servers
}

总结

其余的策略的实现方法比较简单,这里不作详细讲解,具体可以看git的提交记录。同时这次还对 SelectServer 方法进行了修复,增加了对选择的服务器的Status的检查以及选中的服务器不可用时如何选择可用的服务器。我的实现比较简单,可自行探索更为合理的方法。
后续不一定有时间继续更新优化负载均衡器这个项目了。可能会学点别的,发点新的笔记。

其他内容

Lab1:MapReduce

实验一链接

Lab2:Raft

实验二Raft链接

Lab2A:Leader Election

lab2A链接

Lab2B:日志复制

lab2B链接

Lab2C :持久化机制 persistence

lab2C链接

Lab2D:日志压缩 log compaction

lab2D链接

Go web 简单开发 demo

直达gitee链接

Go 实现负载均衡器

负载均衡器原理介绍
版本1.0 demo
版本2.0初版
版本2.1
gitee链接

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值