loadbalancer.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package loadbalancer
  2. import (
  3. "errors"
  4. "github.com/longjoy/micro-go-course/section28/goods/pkg/discovery"
  5. "math/rand"
  6. "sort"
  7. )
  8. // 负载均衡器
  9. type LoadBalancer interface {
  10. SelectService(service []*discovery.InstanceInfo) (*discovery.InstanceInfo, error)
  11. SelectServiceByKey(service []*discovery.InstanceInfo, key string) (*discovery.InstanceInfo, error)
  12. }
  13. func NewRandomLoadBalancer() *RandomLoadBalancer {
  14. return &RandomLoadBalancer{}
  15. }
  16. func NewWeightRoundRobinLoadBalancer() *WeightRoundRobinLoadBalancer {
  17. return &WeightRoundRobinLoadBalancer{}
  18. }
  19. type RandomLoadBalancer struct {
  20. }
  21. // 随机负载均衡
  22. func (loadBalance *RandomLoadBalancer) SelectService(services []*discovery.InstanceInfo) (*discovery.InstanceInfo, error) {
  23. if services == nil || len(services) == 0 {
  24. return nil, errors.New("service instances are not exist")
  25. }
  26. return services[rand.Intn(len(services))], nil
  27. }
  28. func (loadBalance *RandomLoadBalancer) SelectServiceByKey(services []*discovery.InstanceInfo, key string) (*discovery.InstanceInfo, error) {
  29. return loadBalance.SelectService(services)
  30. }
  31. type WeightRoundRobinLoadBalancer struct {
  32. }
  33. // 权重平滑负载均衡
  34. func (loadBalance *WeightRoundRobinLoadBalancer) SelectService(services []*discovery.InstanceInfo) (best *discovery.InstanceInfo, err error) {
  35. if services == nil || len(services) == 0 {
  36. return nil, errors.New("service instances are not exist")
  37. }
  38. total := 0
  39. for i := 0; i < len(services); i++ {
  40. w := services[i]
  41. if w == nil {
  42. continue
  43. }
  44. w.CurWeight += w.Weights.Passing
  45. total += w.Weights.Passing
  46. if best == nil || w.CurWeight > best.CurWeight {
  47. best = w
  48. }
  49. }
  50. if best == nil {
  51. return nil, nil
  52. }
  53. best.CurWeight -= total
  54. return best, nil
  55. }
  56. func (loadBalance *WeightRoundRobinLoadBalancer) SelectServiceByKey(services []*discovery.InstanceInfo, key string) (*discovery.InstanceInfo, error) {
  57. return loadBalance.SelectService(services)
  58. }
  59. func NewHashLoadBalancer() *HashLoadBalancer {
  60. return &HashLoadBalancer{}
  61. }
  62. func (loadBalance *HashLoadBalancer) SelectService(services []*discovery.InstanceInfo) (*discovery.InstanceInfo, error) {
  63. if services == nil || len(services) == 0 {
  64. return nil, errors.New("service instances are not exist")
  65. }
  66. return services[rand.Intn(len(services))], nil
  67. }
  68. type HashLoadBalancer struct {
  69. }
  70. func (loadBalance *HashLoadBalancer) SelectServiceByKey(services []*discovery.InstanceInfo, key string) (*discovery.InstanceInfo, error) {
  71. lens := len(services)
  72. if services == nil || lens == 0 {
  73. return nil, errors.New("service instances are not exist")
  74. }
  75. nodeWeight := make(map[string]int)
  76. instanceMap := make(map[string]*discovery.InstanceInfo)
  77. for i := 0; i < len(services); i++ {
  78. instance := services[i]
  79. nodeWeight[instance.Address] = i
  80. instanceMap[instance.Address] = instance
  81. }
  82. sort.Sort()
  83. // 建立Hash环
  84. hash := NewHashRing()
  85. // 添加各个服务实例到环上
  86. hash.AddNodes(nodeWeight)
  87. // 根据请求的key来获取对应的服务实例
  88. host := hash.GetNode(key)
  89. return instanceMap[host], nil
  90. }