123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- package loadbalancer
- import (
- "errors"
- "github.com/longjoy/micro-go-course/section28/goods/pkg/discovery"
- "math/rand"
- "sort"
- )
- // 负载均衡器
- type LoadBalancer interface {
- SelectService(service []*discovery.InstanceInfo) (*discovery.InstanceInfo, error)
- SelectServiceByKey(service []*discovery.InstanceInfo, key string) (*discovery.InstanceInfo, error)
- }
- func NewRandomLoadBalancer() *RandomLoadBalancer {
- return &RandomLoadBalancer{}
- }
- func NewWeightRoundRobinLoadBalancer() *WeightRoundRobinLoadBalancer {
- return &WeightRoundRobinLoadBalancer{}
- }
- type RandomLoadBalancer struct {
- }
- // 随机负载均衡
- func (loadBalance *RandomLoadBalancer) SelectService(services []*discovery.InstanceInfo) (*discovery.InstanceInfo, error) {
- if services == nil || len(services) == 0 {
- return nil, errors.New("service instances are not exist")
- }
- return services[rand.Intn(len(services))], nil
- }
- func (loadBalance *RandomLoadBalancer) SelectServiceByKey(services []*discovery.InstanceInfo, key string) (*discovery.InstanceInfo, error) {
- return loadBalance.SelectService(services)
- }
- type WeightRoundRobinLoadBalancer struct {
- }
- // 权重平滑负载均衡
- func (loadBalance *WeightRoundRobinLoadBalancer) SelectService(services []*discovery.InstanceInfo) (best *discovery.InstanceInfo, err error) {
- if services == nil || len(services) == 0 {
- return nil, errors.New("service instances are not exist")
- }
- total := 0
- for i := 0; i < len(services); i++ {
- w := services[i]
- if w == nil {
- continue
- }
- w.CurWeight += w.Weights.Passing
- total += w.Weights.Passing
- if best == nil || w.CurWeight > best.CurWeight {
- best = w
- }
- }
- if best == nil {
- return nil, nil
- }
- best.CurWeight -= total
- return best, nil
- }
- func (loadBalance *WeightRoundRobinLoadBalancer) SelectServiceByKey(services []*discovery.InstanceInfo, key string) (*discovery.InstanceInfo, error) {
- return loadBalance.SelectService(services)
- }
- func NewHashLoadBalancer() *HashLoadBalancer {
- return &HashLoadBalancer{}
- }
- func (loadBalance *HashLoadBalancer) SelectService(services []*discovery.InstanceInfo) (*discovery.InstanceInfo, error) {
- if services == nil || len(services) == 0 {
- return nil, errors.New("service instances are not exist")
- }
- return services[rand.Intn(len(services))], nil
- }
- type HashLoadBalancer struct {
- }
- func (loadBalance *HashLoadBalancer) SelectServiceByKey(services []*discovery.InstanceInfo, key string) (*discovery.InstanceInfo, error) {
- lens := len(services)
- if services == nil || lens == 0 {
- return nil, errors.New("service instances are not exist")
- }
- nodeWeight := make(map[string]int)
- instanceMap := make(map[string]*discovery.InstanceInfo)
- for i := 0; i < len(services); i++ {
- instance := services[i]
- nodeWeight[instance.Address] = i
- instanceMap[instance.Address] = instance
- }
- sort.Sort()
- // 建立Hash环
- hash := NewHashRing()
- // 添加各个服务实例到环上
- hash.AddNodes(nodeWeight)
- // 根据请求的key来获取对应的服务实例
- host := hash.GetNode(key)
- return instanceMap[host], nil
- }
|