package sdk import ( "github.com/mhaya/game/game_cluster/internal/data" mhayaLogger "github.com/mhaya/logger" "math/rand" ) // Service 结构体表示单个服务的信息。 type Service struct { NodeId string // 服务的节点地址 Player int Weight float64 // 权重 } // WeightedRoundRobin 是一个结构体,用于管理一组带权重的服务,并支持基于权重的选择逻辑。 type WeightedRoundRobin struct { services []*Service all int total float64 // 所有服务的总权重 } // NewWeightedRoundRobin 创建一个新的 WeightedRoundRobin 实例。 func NewWeightedRoundRobin(maps map[string]int) *WeightedRoundRobin { serviceConfig, ok := data.ServerConfig.Get() if !ok { mhayaLogger.Warnf("[NewWeightedRoundRobin] weighted round robin service config is nil") return nil } wrr := &WeightedRoundRobin{ services: nil, } var services []*Service for k, v := range maps { wrr.all += v services = append(services, &Service{ NodeId: k, Player: v, }) } wrr.services = services avg := wrr.all / len(wrr.services) for _, service := range services { if service.Player-avg <= 3*serviceConfig.Range { service.Weight = float64(serviceConfig.Weight.Max) } else if service.Player-avg < 2*serviceConfig.Range { service.Weight = float64(serviceConfig.Weight.Middle) } else { service.Weight = float64(serviceConfig.Weight.Min) } if service.Player >= serviceConfig.Expansion { service.Weight = float64(serviceConfig.Weight.Min) } if service.Player >= serviceConfig.Max { service.Weight = 0 } } for _, s := range services { wrr.total += s.Weight } return wrr } // Pick 使用加权轮询的方式选取一个服务。 func (w *WeightedRoundRobin) Pick() *Service { if len(w.services) == 0 { return nil } // 随机选择一个介于[0, total)之间的数字 target := rand.Float64() * w.total var current float64 = 0.0 // 循环直到找到正确的服务 for _, service := range w.services { current += service.Weight if current >= target { return service } } // 如果因浮点数精度问题未能命中,则返回最后一个服务 return w.services[len(w.services)-1] }