discover/LoadBalancer.go

48 lines
1.5 KiB
Go
Raw Normal View History

package discover
import (
"net/http"
"time"
)
// SetLoadBalancer 设置全局负载均衡策略
func SetLoadBalancer(lb LoadBalancer) {
DefaultDiscoverer.SetLoadBalancer(lb)
}
// SetLoadBalancer 设置负载均衡策略
func (d *Discoverer) SetLoadBalancer(lb LoadBalancer) {
d.settedLoadBalancer = lb
}
// LoadBalancer 负载均衡接口
type LoadBalancer interface {
// Response 在每个请求完成后调用,用于更新节点状态
Response(appClient *AppClient, node *NodeInfo, err error, response *http.Response, responseTime time.Duration)
// Next 根据当前可用节点选择一个最优节点
Next(appClient *AppClient, nodes []*NodeInfo, request *http.Request) *NodeInfo
}
// DefaultLoadBalancer 默认负载均衡器(简单权重轮询/得分最小者优先)
type DefaultLoadBalancer struct{}
// Response 在默认负载均衡器中不再执行写操作,减少锁竞争
func (lb *DefaultLoadBalancer) Response(appClient *AppClient, node *NodeInfo, err error, response *http.Response, responseTime time.Duration) {
}
// Next 根据得分UsedTimes / Weight选择得分最小的节点
func (lb *DefaultLoadBalancer) Next(appClient *AppClient, nodes []*NodeInfo, request *http.Request) *NodeInfo {
var minScore float64 = -1
var minNode *NodeInfo
for _, node := range nodes {
// 动态计算得分,避免使用 sync.Map 存储,减少内存分配和锁竞争
score := float64(node.UsedTimes.Load()) / float64(node.Weight)
if minNode == nil || score < minScore {
minScore = score
minNode = node
}
}
return minNode
}